奇迹969

 

爬虫之数据解析

bs4

xpath

爬虫的分类:
通用:
聚焦:数据解析
增量式:监测
http:客户端和服务器端进行数据交互的形式
证书密钥加密:
什么是证书?
证书种包含的是经过数字签名的公钥
反爬:
robots
UA伪装
请求载体的身份标识
在headers种应用一个字典(请求头信息:UA)
动态加载的数据
如何处理动态请求参数:
封装到一个字典中,字典需要作用到data或者params

 

 

数据解析
数据解析的作用
用于获取页面中局部的页面源码数据
如何实现数据解析
正则
bs4(独有)
xpath(最为通用)
pyquery(自学)
数据解析的通用原理是什么?
标签定位
将标签中间存储的文本数据或者其属性值进行捕获

 

 

正则解析¶
需求:爬取糗事百科中的图片数据
确认了页面中没有动态加载数据的存在



import requests
import os
import re
from urllib import request
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
}
#封装一个通用的url模板(不可变)
url = 'https://www.qiushibaike.com/pic/page/%d/'

dirName = './qiutuLibs'
if not os.path.exists(dirName):
    os.mkdir(dirName)
    
for page in range(1,3):
    print('正在爬取第{}页的图片数据......'.format(page))
    #拼接成了某一个页码对应的完整的url
    new_url = format(url%page)
    #获取页面源码数据(字符串)
    page_text = requests.get(url=new_url,headers=headers).text
    #数据解析:图片img标签中的src的属性值解析出来
    ex = '<div class="thumb">.*?<img src="(.*?)" alt=.*?</div>'
    img_src_list = re.findall(ex,page_text,re.S)
    for img_src in img_src_list:
        #就是一个完整的图片地址
        img_src = 'https:'+img_src
        img_name = img_src.split('/')[-1]
        img_path = dirName+'/'+img_name
        request.urlretrieve(img_src,img_path)
        print(img_name,'下载成功!!!')

 

bs4解析

  • 环境的安装:
    • pip install bs4
    • pip install lxml
  • bs4解析原理
    • 实例化一个BeautifulSoup的对象,且将即将被解析的页面源码加载到该对象中
    • 使用该对象中的属性或者方法进行标签定位和数据提取
  • BeautifulSoup对象的实例化方式:lxml就是一款解析器
    • BeautifulSoup(fp,'lxml'):将本地存储的html文档加载到该对象中
    • BeautifulSoup(page_text,'lxml'):将互联网上获取的html源码加载到该对象中
 
  • 将本地的test.html文档中相关的数据进行解析
from bs4 import BeautifulSoup
from bs4 import BeautifulSoup
fp = open('./test.html','r',encoding='utf-8')
soup = BeautifulSoup(fp,'lxml')
soup
实现标签的定位
soup.title
<title>测试bs4</title>
soup.div
<div>
<p>百里守约</p>
</div>
总结:
soup.tagName:返回的就是页面中第一次出现的tagName标签(返回的是一个单数)





find函数的用法:属性定位 soup.find(
'tagName',attrName='value') 注意:返回的是单数 soup.find('div',class_='song') <div class="song"> <p>李清照</p> <p>王安石</p> <p>苏轼</p> <p>柳宗元</p> <a href="http://www.song.com/" target="_self" title="赵匡胤"> <span>this is span</span> 宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱</a> <a class="du" href="">总为浮云能蔽日,长安不见使人愁</a> <img alt="" src="http://www.baidu.com/meinv.jpg"/> </div>



soup.find_all(
'tagName'):定位所有的tagName的标签 soup.find_all('tagName',attrName='value'):属性定位 注意:返回值是列表 soup.find_all('div') <div class="tang"> <ul> <li><a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a></li> <li><a href="http://www.163.com" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a></li> <li><a alt="qi" href="http://www.126.com">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li> <li><a class="du" href="http://www.sina.com">杜甫</a></li> <li><a class="du" href="http://www.dudu.com">杜牧</a></li> <li><b>杜小月</b></li> <li><i>度蜜月</i></li> <li><a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a></li> </ul> </div>





select(
'选择器'):根据选择器进行标签定位且返回的是复数(列表) 类选择器,id选择器,标签选择器,层级选择器 层级选择器:>表示一个层级,空格表示多个层级 soup.select('.tang') [<div class="tang"> <ul> <li><a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a></li> <li><a href="http://www.163.com" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a></li> <li><a alt="qi" href="http://www.126.com">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li> <li><a class="du" href="http://www.sina.com">杜甫</a></li> <li><a class="du" href="http://www.dudu.com">杜牧</a></li> <li><b>杜小月</b></li> <li><i>度蜜月</i></li> <li><a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a></li> </ul> </div>] soup.select('.tang > ul > li') [<li><a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a></li>, <li><a href="http://www.163.com" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a></li>, <li><a alt="qi" href="http://www.126.com">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li>, <li><a class="du" href="http://www.sina.com">杜甫</a></li>, <li><a class="du" href="http://www.dudu.com">杜牧</a></li>, <li><b>杜小月</b></li>, <li><i>度蜜月</i></li>, <li><a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a></li>] soup.select('.tang li') [<li><a href="http://www.baidu.com" title="qing">清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村</a></li>, <li><a href="http://www.163.com" title="qin">秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山</a></li>, <li><a alt="qi" href="http://www.126.com">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li>, <li><a class="du" href="http://www.sina.com">杜甫</a></li>, <li><a class="du" href="http://www.dudu.com">杜牧</a></li>, <li><b>杜小月</b></li>, <li><i>度蜜月</i></li>, <li><a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a></li>] 取数据(属性值和标签中存储的文本数据)







soup.p.string
'百里守约' soup.p.text '百里守约' soup.find('div',class_='song').text '\n李清照\n王安石\n苏轼\n柳宗元\n\nthis is span\n\t\t宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱\n总为浮云能蔽日,长安不见使人愁\n\n' text和string的区别? string获取的是标签中直系的文本内容 text获取的是标签中所有的文本内容 取属性:

tag[
'attrName'] for a in soup.select('.tang > ul > li > a'): print(a['href']) http://www.baidu.com http://www.163.com http://www.126.com http://www.sina.com http://www.dudu.com http://www.haha.com








需求:爬取三国演义小说所有内容 url
= 'http://www.shicimingju.com/book/sanguoyanyi.html' page_text = requests.get(url=url,headers=headers).text ​ #使用bs4进行数据解析(章节标题&内容) soup = BeautifulSoup(page_text,'lxml') a_list = soup.select('.book-mulu > ul > li > a') fp = open('sanguo.txt','w',encoding='utf-8') for a in a_list: title = a.string detail_url = 'http://www.shicimingju.com'+a['href'] #对详情页的url发起请求解析出章节内容 detail_page_text = requests.get(url=detail_url,headers=headers).text detail_soup = BeautifulSoup(detail_page_text,'lxml') content = detail_soup.find('div',class_='chapter_content').text fp.write(title+':'+content+'\n') print(title,'保存成功!!!') fp.close() soup.TagName soup.find soup.find_all soup.select tag.string/text tag['attrName']

 

 

 

xpath解析
环境安装:pip install lxml
解析原理:
实例化一个etree类型的对象,且将即将被解析的页面源码数据加载到该对象中
调用该对象中的xpath方法结合着不同的xpath表达式进行标签定位和数据提取
实例化对象:






etree.parse(fileName) etree.HTML(page_text)
from lxml import etree # from lxml.html.clean import tree tree = etree.parse('test.html')
基于标签定位的xpath表达式 tree.xpath(
'/html/head/meta') [] tree.xpath('//meta') [<Element meta at 0x1e9a1d27848>] xpath方法返回值永远是一个列表 xpath表达式中最左侧的/和//的区别是什么? /表示我们必须从根标签进行定位 //表示我们可以从任意位置标签定位 tree.xpath('//div') [<Element div at 0x1e9a21ed748>, <Element div at 0x1e9a1e269c8>, <Element div at 0x1e9a1e26608>]

属性定位 tree.xpath(
'//div[@class="song"]') [<Element div at 0x1e9a1e269c8>] 索引定位 索引值是从1开始 在xpath表达式中非最左侧的/和//的区别? /表示一个层级 //表示多个层级 tree.xpath('//div[@class="tang"]/ul/li[3]') [<Element li at 0x1e9a1d27a88>] tree.xpath('//div[@class="tang"]//li[3]') [<Element li at 0x1e9a1d27a88>] 取文本(/text() //text()) /text():获取的是标签下直系的文本数据 //text():获取的是标签下所有的文本数据 tree.xpath('//div[@class="tang"]//li[5]/a/text()') ['杜牧'] string_list = tree.xpath('//div[@class="tang"]//text()') ''.join(string_list) '\n\t\t\n\t\t\t清明时节雨纷纷,路上行人欲断魂,借问酒家何处有,牧童遥指杏花村\n\t\t\t秦时明月汉时关,万里长征人未还,但使龙城飞将在,不教胡马度阴山\n\t\t\t岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君\n\t\t\t杜甫\n\t\t\t杜牧\n\t\t\t杜小月\n\t\t\t度蜜月\n\t\t\t凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘\n\t\t\n\t' 取属性(@) tree.xpath('//div[@class="tang"]//li[5]/a/@href') ['http://www.dudu.com']







需求:爬取boss中的岗位信息(岗位名称,薪资,公司名称,岗位描述) url
= 'https://www.zhipin.com/c101010100/?query=python爬虫&page=%d' fp = open('boss.txt','w',encoding='utf-8') for page in range(1,3): new_url = format(url%page) page_text = requests.get(url=new_url,headers=headers).text #xpath的数据解析 tree = etree.HTML(page_text) #tree中存储的是整张页面对应的页面源码数据 li_list = tree.xpath('//div[@class="job-list"]/ul/li') for li in li_list: job_title = li.xpath('./div/div[1]/h3/a/div[1]/text()')[0]#li中存储的是局部的li标签对应的页面源码数据 salary = li.xpath('./div/div[1]/h3/a/span/text()')[0] detail_url = 'https://www.zhipin.com'+li.xpath('./div/div[1]/h3/a/@href')[0] company_name = li.xpath('.//div[@class="company-text"]/h3/a/text()')[0] detail_page_text = requests.get(url=detail_url,headers=headers).text detail_tree = etree.HTML(detail_page_text) job_desc = detail_tree.xpath('//*[@id="main"]/div[3]/div/div[2]/div[2]/div[1]/div//text()') job_desc = ''.join(job_desc) fp.write(job_title+':'+salary+':'+company_name+':'+job_desc+'\n\n\n') fp.close()







处理中文乱码 url
= 'http://pic.netbian.com/4kmeinv/index_%d.html' for page in range(1,6): if page == 1: new_url = 'http://pic.netbian.com/4kmeinv/' else: new_url = format(url%page) response = requests.get(url=new_url,headers=headers) # response.encoding = 'utf-8' page_text = response.text tree = etree.HTML(page_text) li_list = tree.xpath('//*[@id="main"]/div[3]/ul/li') for li in li_list: img_src = 'http://pic.netbian.com'+li.xpath('./a/img/@src')[0] img_name = li.xpath('./a/b/text()')[0] img_name = img_name.encode('iso-8859-1').decode('gbk') ​ http://pic.netbian.com/uploads/allimg/180703/142018-15305988184e63.jpg 姜璐4k壁纸 http://pic.netbian.com/uploads/allimg/190713/100152-15629833120209.jpg 克拉女神-蓓颖 风度娴雅 http://pic.netbian.com/uploads/allimg/190608/130131-1559970091ea9b.jpg 双手托腮的美女4k壁纸图 http://pic.netbian.com/uploads/allimg/190427/210756-1556370476a05f.jpg 欣怡4k壁纸 http://pic.netbian.com/uploads/allimg/190328/210949-155377858946d0.jpg 克拉女神 晓晓4k壁纸384 https://www.aqistudy.cn/historydata/ 爬取所有的城市名称 url = 'https://www.aqistudy.cn/historydata/' page_text = requests.get(url=url,headers=headers).text ​ tree = etree.HTML(page_text) # hot_cities = tree.xpath('//div[@class="bottom"]/ul/li/a/text()') # all_cities = tree.xpath('//div[@class="bottom"]/ul/div[2]/li/a/text()') #大大滴增强xpath表达式的通用性 cities = tree.xpath('//div[@class="bottom"]/ul/div[2]/li/a/text() | //div[@class="bottom"]/ul/li/a/text()') print(cities) ['北京', '上海', '广州', '深圳', '杭州', '天津', '成都', '南京', '西安', '武汉', '阿坝州', '安康', '阿克苏地区', '阿里地区', '阿拉善盟', '阿勒泰地区', '安庆', '安顺', '鞍山', '克孜勒苏州', '安阳', '蚌埠', '白城', '保定', '北海', '宝鸡', '北京', '毕节', '博州', '白山', '百色', '保山', '白沙', '包头', '保亭', '本溪', '巴彦淖尔', '白银', '巴中', '滨州', '亳州', '长春', '昌都', '常德', '成都', '承德', '赤峰', '昌吉州', '五家渠', '昌江', '澄迈', '重庆', '长沙', '常熟', '楚雄州', '朝阳', '沧州', '长治', '常州', '潮州', '郴州', '池州', '崇左', '滁州', '定安', '丹东', '东方', '东莞', '德宏州', '大理州', '大连', '大庆', '大同', '定西', '大兴安岭地区', '德阳', '东营', '黔南州', '达州', '德州', '儋州', '鄂尔多斯', '恩施州', '鄂州', '防城港', '佛山', '抚顺', '阜新', '阜阳', '富阳', '抚州', '福州', '广安', '贵港', '桂林', '果洛州', '甘南州', '固原', '广元', '贵阳', '甘孜州', '赣州', '广州', '淮安', '海北州', '鹤壁', '淮北', '河池', '海东地区', '邯郸', '哈尔滨', '合肥', '鹤岗', '黄冈', '黑河', '红河州', '怀化', '呼和浩特', '海口', '呼伦贝尔', '葫芦岛', '哈密地区', '海门', '海南州', '淮南', '黄南州', '衡水', '黄山', '黄石', '和田地区', '海西州', '河源', '衡阳', '汉中', '杭州', '菏泽', '贺州', '湖州', '惠州', '吉安', '金昌', '晋城', '景德镇', '金华', '西双版纳州', '九江', '吉林', '即墨', '江门', '荆门', '佳木斯', '济南', '济宁', '胶南', '酒泉', '句容', '湘西州', '金坛', '鸡西', '嘉兴', '江阴', '揭阳', '济源', '嘉峪关', '胶州', '焦作', '锦州', '晋中', '荆州', '库尔勒', '开封', '黔东南州', '克拉玛依', '昆明', '喀什地区', '昆山', '临安', '六安', '来宾', '聊城', '临沧', '娄底', '乐东', '廊坊', '临汾', '临高', '漯河', '丽江', '吕梁', '陇南', '六盘水', '拉萨', '乐山', '丽水', '凉山州', '陵水', '莱芜', '莱西', '临夏州', '溧阳', '辽阳', '辽源', '临沂', '龙岩', '洛阳', '连云港', '莱州', '兰州', '林芝', '柳州', '泸州', '马鞍山', '牡丹江', '茂名', '眉山', '绵阳', '梅州', '宁波', '南昌', '南充', '宁德', '内江', '南京', '怒江州', '南宁', '南平', '那曲地区', '南通', '南阳', '平度', '平顶山', '普洱', '盘锦', '蓬莱', '平凉', '莆田', '萍乡', '濮阳', '攀枝花', '青岛', '琼海', '秦皇岛', '曲靖', '齐齐哈尔', '七台河', '黔西南州', '清远', '庆阳', '钦州', '衢州', '泉州', '琼中', '荣成', '日喀则', '乳山', '日照', '韶关', '寿光', '上海', '绥化', '石河子', '石家庄', '商洛', '三明', '三门峡', '山南', '遂宁', '四平', '商丘', '宿迁', '上饶', '汕头', '汕尾', '绍兴', '三亚', '邵阳', '沈阳', '十堰', '松原', '双鸭山', '深圳', '朔州', '宿州', '随州', '苏州', '石嘴山', '泰安', '塔城地区', '太仓', '铜川', '屯昌', '通化', '天津', '铁岭', '通辽', '铜陵', '吐鲁番地区', '铜仁地区', '唐山', '天水', '太原', '台州', '泰州', '文昌', '文登', '潍坊', '瓦房店', '威海', '乌海', '芜湖', '武汉', '吴江', '乌兰察布', '乌鲁木齐', '渭南', '万宁', '文山州', '武威', '无锡', '温州', '吴忠', '梧州', '五指山', '西安', '兴安盟', '许昌', '宣城', '襄阳', '孝感', '迪庆州', '锡林郭勒盟', '厦门', '西宁', '咸宁', '湘潭', '邢台', '新乡', '咸阳', '新余', '信阳', '忻州', '徐州', '雅安', '延安', '延边州', '宜宾', '盐城', '宜昌', '宜春', '银川', '运城', '伊春', '云浮', '阳江', '营口', '榆林', '玉林', '伊犁哈萨克州', '阳泉', '玉树州', '烟台', '鹰潭', '义乌', '宜兴', '玉溪', '益阳', '岳阳', '扬州', '永州', '淄博', '自贡', '珠海', '湛江', '镇江', '诸暨', '张家港', '张家界', '张家口', '周口', '驻马店', '章丘', '肇庆', '中山', '舟山', '昭通', '中卫', '张掖', '招远', '资阳', '遵义', '枣庄', '漳州', '郑州', '株洲']

 

pyquery库是jQuery的Python实现,能够以jQuery的语法来操作解析 HTML 文档,易用性和解析速度都很好,和它差不多的还有BeautifulSoup,都是用来解析的。相比BeautifulSoup完美翔实的文档,虽然PyQuery库的文档弱爆了, 但是使用起来还是可以的,有些地方用起来很方便简洁。
PyQuery库官方文档

初始化为PyQuery对象
常用的CCS选择器
伪类选择器
查找标签
获取标签信息

初始化为PyQuery对象
html = """
<html lang="en">
    <head>
        简单好用的
        <title>PyQuery</title>
    </head>
    <body>
        <ul id="container">
            <li class="object-1">Python</li>
            <li class="object-2">大法</li>
            <li class="object-3">好</li>
        </ul>
    </body>
</html>
"""

相当于BeautifulSoup库的初识化方法,将html转化为BeautifulSoup对象。
bsObj = BeautifulSoup(html, 'html.parser')
PyQuery库也要有自己的初始化。
1.1 将字符串初始化
from pyquery import PyQuery as pq
#初始化为PyQuery对象
doc = pq(html)
print(type(doc))
print(doc)

返回
<class 'pyquery.pyquery.PyQuery'>

<html lang="en">
    <head>
        <title>PyQuery学习</title>
    </head>
    <body>
        <ul id="container">
            <li class="object-1"/>
            <li class="object-2"/>
            <li class="object-3"/>
        </ul>
    </body>
</html>

1.2 将html文件初始化
#filename参数为html文件路径
test_html = pq(filename = 'test.html')
print(type(test_html))
print(test_html)

返回
<class 'pyquery.pyquery.PyQuery'><html lang="en">
    <head>
        <title>PyQuery学习</title>
    </head>
    <body>
        <ul id="container">
            <li class="object-1"/>
            <li class="object-2"/>
            <li class="object-3"/>
        </ul>
    </body>
</html>

1.3 对网址响应进行初始化
response = pq(url = 'https://www.baidu.com')
print(type(response))
print(response)

返回
<class 'pyquery.pyquery.PyQuery'>

<html> <head><meta http-equiv="content-type" content="text/html;charset=utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=Edge"/><meta content="always" name="referrer"/><link rel="stylesheet" type="text/css" href="https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css"/><title>ç�¾åº¦ä¸�ä¸�ï¼�ä½ å°±ç�¥é��</title></head> <body link="#0000cc"> <div id="wrapper"> <div id="head"> <div class="head_wrapper"> <div class="s_form"> <div class="s_form_wrapper"> <div id="lg"> <img hidefocus="true" src="//www.baidu.com/img/bd_logo1.png" width="270" height="129"/> </div> <form id="form" name="f" action="//www.baidu.com/s" class="fm"> <input type="hidden" name="bdorz_come" value="1"/> <input type="hidden" name="ie" value="utf-8"/> <input type="hidden" name="f" value="8"/> <input type="hidden" name="rsv_bp" value="1"/> <input type="hidden" name="rsv_idx" value="1"/> <input type="hidden" name="tn" value="baidu"/><span class="bg s_ipt_wr"><input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off" autofocus="autofocus"/></span><span class="bg s_btn_wr"><input type="submit" id="su" value="ç�¾åº¦ä¸�ä¸�" class="bg s_btn" autofocus=""/></span> </form> </div> </div> <div id="u1"> <a href="http://news.baidu.com" name="tj_trnews" class="mnav">æ�°é�»</a> <a href="https://www.hao123.com" name="tj_trhao123" class="mnav">hao123</a> <a href="http://map.baidu.com" name="tj_trmap" class="mnav">å�°å�¾</a> <a href="http://v.baidu.com" name="tj_trvideo" class="mnav">è§�é¢�</a> <a href="http://tieba.baidu.com" name="tj_trtieba" class="mnav">è´´å�§</a> <noscript> <a href="http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1" name="tj_login" class="lb">ç�»å½�</a> </noscript> <script>document.write('&lt;a href="http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&amp;")+ "bdorz_come=1")+ '" name="tj_login" class="lb"&gt;ç�»å½�&lt;/a&gt;');&#13;</script> <a href="//www.baidu.com/more/" name="tj_briicon" class="bri" style="display: block;">æ�´å¤�产å��</a> </div> </div> </div> <div id="ftCon"> <div id="ftConw"> <p id="lh"> <a href="http://home.baidu.com">å
³äº�ç�¾åº¦</a> <a href="http://ir.baidu.com">About Baidu</a> </p> <p id="cp">©2017 Baidu <a href="http://www.baidu.com/duty/">使ç�¨ç�¾åº¦å��å¿
读</a>  <a href="http://jianyi.baidu.com/" class="cp-feedback">����</a> 京ICP�030173�  <img src="//www.baidu.com/img/gs.gif"/> </p> </div> </div> </div> </body> </html>

二、常用的CCS选择器
打印id为container的标签
print(doc('#container'))
print(type(doc('#container')))

返回
<ul id="container">
    <li class="object-1"/>
    <li class="object-2"/>
    <li class="object-3"/>
</ul>


<class 'pyquery.pyquery.PyQuery'>

打印class为object-1的标签
print(doc('.object-1'))

返回
<li class="object-1"/>

打印标签名为body的标签
print(doc('body'))

返回
<body>
    <ul id="container">
        <li class="object-1"/>
        <li class="object-2"/>
        <li class="object-3"/>
    </ul>
</body>

多种css选择器使用
print(doc('html #container'))

返回
<ul id="container">
    <li class="object-1"/>
    <li class="object-2"/>
    <li class="object-3"/>
</ul>

三、伪类选择器
伪类nth
print(pseudo_doc('li:nth-child(2)'))

#打印第一个li标签
print(pseudo_doc('li:first-child'))

#打印最后一个标签
print(pseudo_doc('li:last-child'))

返回
<li class="object-2">大法</li>
<li class="object-1">Python</li>
<li class="object-6">好玩</li>

contains
#找到含有Python的li标签
print(pseudo_doc("li:contains('Python')"))

#找到含有好的li标签
print(pseudo_doc("li:contains('好')"))

返回
<li class="object-1">Python</li>
<li class="object-3">好</li>
<li class="object-4">好</li>
<li class="object-6">好玩</li>  

四、查找标签
按照条件在Pyquery对象中查找符合条件的标签,类似于BeautifulSoup中的find方法。
打印id=container的标签
print(doc.find('#container'))

返回
<ul id="container">
    <li class="object-1"/>
    <li class="object-2"/>
    <li class="object-3"/>
</ul>

print(doc.find('li'))

返回
<li class="object-1"/>
<li class="object-2"/>
<li class="object-3"/>

4.2 子辈标签-children方法
#id=container的标签的子辈标签
container = doc.find('#container')
print(container.children())

返回
<li class="object-1"/>
<li class="object-2"/>
<li class="object-3"/>

4.3 父辈标签-parent方法
object_2 = doc.find('.object-2')
print(object_2.parent())

返回
<ul id="container">
    <li class="object-1"/>
    <li class="object-2"/>
    <li class="object-3"/>
</ul>

4.4 兄弟标签-siblings方法
object_2 = doc.find('.object-2')
print(object_2.siblings())

返回
<li class="object-1"/>
<li class="object-3"/>

五、获取标签的信息
定位到目标标签后,我们需要标签内部的文本或者属性值,这时候需要进行提取文本或属性值操作
5.1 标签属性值的提取
.attr() 传入 标签的属性名,返回属性值
object_2 = doc.find('.object-2')
print(object_2.attr('class'))

返回
object-2

5.2 标签内的文本
.text()
html_text = """
<html lang="en">
    <head>
        简单好用的
        <title>PyQuery</title>
    </head>
    <body>
        <ul id="container">
            Hello World!
            <li class="object-1">Python</li>
            <li class="object-2">大法</li>
            <li class="object-3">好</li>
        </ul>
    </body>
</html>
"""

docs = pq(html_text)
print(docs.text())

返回
简单好用的 PyQuery Hello World! Python 大法 好

object_1 = docs.find('.object-1')
print(object_1.text())
container = docs.find('#container')
print(container.text())

返回
Python

Hello World! Python 大法 好

tips:如果我只想获得Hello World这个,不想得到其他的文本,可以使用remove方法将li标签去掉,然后再使用text方法
container = docs.find('#container')
container.remove('li')
print(container.text())

返回
Hello World!

pyquery一些自定义的用法
访问网址
PyQuery与BeautifulSoup对比,我们会发现PyQuery可以对网址发起请求。 比如
from pyquery import PyQuery
PyQuery(url = 'https://www.baidu.com')

opener参数
这是PyQuery对百度网址进行请求,并将请求返回的响应数据处理为PyQuery对象。一般pyquery库会默认调用urllib库,如果想使用selenium或者requests库,可以自定义PyQuery的opener参数。
opener参数作用是告诉pyquery用什么请求库对网址发起请求。常见的请求库如urllib、requests、selenium。这里我们自定义一个selenium的opener。
from pyquery import PyQuery
from selenium.webdriver import PhantomJS

#用selenium访问url
def selenium_opener(url):
    #我没有将Phantomjs放到环境变量,所以每次用都要放上路径
    driver = PhantomJS(executable_path = 'phantomjs的路径')
    driver.get(url)
    html = driver.page_source
    driver.quit()
    return html

#注意,使用时opener参数是函数名,没有括号的!
PyQuery(url='https://www.baidu.com/', opener=selenium_opener)

这时候我们就能对PyQuery对象进行操作,提取有用的信息。具体请看上次的分享,如果想了解更多的功能,pyquery文档写的不怎么详细,好在基本跟jQuery功能吻合,我们如果想用好pyquery,需要查看jQuery文档。
cookies、headers
在requests用法中,一般为了访问网址更加真实,模仿成浏览器。一般我们需要传入headers,必要的时候还需要传入cookies参数。而pyquery库就有这功能,也能伪装浏览器。
from pyquery import PyQuery

cookies = {'Cookie':'你的cookie'}
headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'}


PyQuery(url='https://www.baidu.com/',headers=headers,cookies=cookies)

让你的selenium带上pyquery功能
让driver访问的网址得到的网页直接变为PyQuery对象,更方便提取数据
from pyquery import PyQuery
from selenium.webdriver import PhantomJS

class Browser(PhantomJS):
    @property    
    def dom(self):
        return PyQuery(self.page_source)"""
这部分property是装饰器,需要知道@property下面紧跟的函数,实现了类的属性功能。
这里browser.dom,就是browser的dom属性。
"""

browser = Browser(executable_path='phantomjs的路径')
browser.get(url='https://www.baidu.com/')
print(type(browser.dom))

返回
<class 'pyquery.pyquery.PyQuery'>



 

posted on 2019-08-02 14:55  奇迹969  阅读(334)  评论(0编辑  收藏  举报

导航