参考资料:PYTHON PYQUERY 基本用法
安装PyQuery
pip install pyquery
使用方法
# 引用
from pyquery import PyQuery as pq
# 初始化
from pyquery import PyQuery as pq
doc =pq(html) #解析html字符串
doc =pq("http://news.baidu.com/") #解析网页
doc =pq("./a.html") #解析html 文本
print("类型为:%s"%type(items))
# 类型为:<class 'pyquery.pyquery.PyQuery'>
# CSS选择器
doc('#id .class tag')
## 元素查找
# 查找子元素(相当于往深处进一层)
doc.children()
# 查找父元素(相当于首先进若干层,再退一层)
doc('#id .class tag').parent()
# 查找兄弟元素(siblings返回了同级的其他标签)
doc('#id .class tag').siblings()
# 遍历元素
for it in doc('a').items():
# 获取属性信息
print(it.attr('href'))
print(it.attr.href)
# 获取文本(标签分割的文本应直接相连)
print(it.text())
# 获取 HTML信息(外层标签内标签和文本的混合体) 比如'<a>asdadasdad12312</a>'
print(it.html())
## 另有常用DOM操作
# 添加 移除
doc = pq(html)
its=doc("link").items()
for it in its:
print("添加:%s"%it.addClass('active1'))
print("移除:%s"%it.removeClass('active1'))
# attr 为获取/修改属性 css 添加style属性
doc = pq(html)
its=doc("link").items()
for it in its:
print("修改:%s"%it.attr('class','active'))
print("添加:%s"%it.css('font-size','14px'))
# remove 移除标签
doc = pq(html)
its=doc("div")
print('移除前获取文本结果:\n%s'%its.text())
it=its.remove('ul')
print('移除后获取文本结果:\n%s'%it.text())
## 伪类选择器
doc = pq(html)
its=doc("link:first-child")
print('第一个标签:%s'%its)
its=doc("link:last-child")
print('最后一个标签:%s'%its)
its=doc("link:nth-child(2)")
print('第二个标签:%s'%its)
its=doc("link:gt(0)") #从零开始
print("获取0以后的标签:%s"%its)
its=doc("link:nth-child(2n-1)")
print("获取奇数标签:%s"%its)
its=doc("link:contains('hello')")
print("获取文本包含hello的标签:%s"%its)
更多css选择器可以查看:
http://www.w3school.com.cn/css/index.asp
爬取页面中文乱码问题
创建PyQuery对象时 写明编码集
html=PyQuery('http://www.sina.com.cn',encoding='utf-8')
参考资料:Python爬虫 PyQuery爬取中文页面乱码问题
实践:抓取2020年春季人教版教科书
首页:
http://bp.pep.com.cn/jc/
主页进入分页的方式:
大区是 response(’.list_sjzl_jcdzs2020’).items() ,名称来自 div.find(’.container_title_jcdzs2020’).text()
分页:
进一步,小区是 div(‘li a’).items(),名称来自 subdiv.text()
建立文件目录结构为 E:\教材+\+大区名称+\+小区名称+\+文件名
这个网站没有robots.txt,也没有通过cookies或headers实现防盗链,直接抓取即可。
不过还是使用单线程,每下载一个文件间隔一段时间,避免把网站爬瘫了,面临法律上的风险(参考资料)
完整代码:
# coding: utf-8
import os
import requests
import time
from pyquery import PyQuery as pq
def parse_pdf(url, path, filename):
# print(url)
while True:
try:
os.system('mkdir ' + path)
# 如果网站以相同页面格式增量更新,已下载的文件无需重复下载
if os.path.isfile(path + filename):
print('文件' + filename + '已存在!')
return False
with open(path + filename, 'wb') as f:
print(url + ' : ' + path + filename)
f.write(requests.get(url).content)
except:
time.sleep(3)
continue
break
return True
def parse_subpage(url, path):
response = pq(url,encoding='utf-8')
# print(url)
for div in response('.fl').items():
# print(div.find('h6 a').text().encode('utf8'))
if parse_pdf(url + div.find('.btn_type_dl').attr.href, path, div.find('h6 a').text() + '.pdf'):
time.sleep(1)
def parse_homepage(url, path):
response = pq(url,encoding='utf-8')
# print(url)
for div in response('.list_sjzl_jcdzs2020').items():
for subdiv in div('li a').items():
parse_subpage(url + subdiv.attr.href,
path + div.find('.container_title_jcdzs2020').text() + '\\'
+ subdiv.text() + '\\')
print('完成一小区' + div.find('.container_title_jcdzs2020').text() + ' : ' + subdiv.text())
time.sleep(5)
print('完成一大区' + div.find('.container_title_jcdzs2020').text())
time.sleep(20)
# 主函数
def main():
url = 'http://bp.pep.com.cn/jc/'
path = 'E:\\教材\\'
parse_homepage(url, path)
if __name__=='__main__':
main()