网络爬虫的三种解析方式 -- 2019-08-08 18:01:21
Posted gqy02
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络爬虫的三种解析方式 -- 2019-08-08 18:01:21相关的知识,希望对你有一定的参考价值。
原文: http://106.13.73.98/__/132/
三种解析方式
- 正则解析
- Xpath解析
- BeautifulSoup解析
本文将详细为大家讲解三种聚焦爬虫中的数据解析方式。
requests模块可实现数据爬取的流程
- 指定url
- 基于requests模块发起请求
- 获取响应对象中的数据
- 进行持久化存储
???????其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需要进行指定数据解析。因为,在大多数情况下,我们都是指定去使用聚焦爬虫,也就是爬取页面中指定部分的数据值,而不是整个页面的数据。因此,本文将详细为大家讲解三种聚焦爬虫中的数据解析方式。至此,我们的数据爬取流程可以修改为:
- 指定url
- 基于requests模块发起请求
- 获取响应中的数据
数据解析
- 进行持久化存储
正则解析
注:这里将从Python语言的视角讲解
re.I
忽略大小写
re.M
多行匹配
re.S
单行匹配
.*
贪婪模式
.*?
非贪婪(惰性)模式
?
0次或1次
+
1次或多次
*
0次或1次或多次
m
固定m次
m,
至少m次
m, n
m-n次
(\d?)
分组
(?P<name>\d?)
分组命名
(?P=name)
引用前面定义的命名分组
(?:\d?)
取消分组优先
(\d?)\1\1
通过默认分组编号向后引用(这里将匹配3个相同的数字)
(?<=pattern)
向后肯定断言的语法
关于正则的更多介绍,可见此文献:【正则表达式介绍篇】
Xpath解析
pip install lxml
示例
我们先准备好用于测试的html页面:<html lang="en"> <head> <meta charset="UTF-8" /> <title>Xpath解析测试</title> </head> <body> <div> <p>百里守约</p> </div> <div class="song"> <p>李清照</p> <p>王安石</p> <p>苏轼</p> <p>柳宗元</p> <a href="http://www.song.com/" title="赵匡胤" target="_self"> <span>this is span</span> 宋朝是最强大的王朝,不是军队的强大,而是经济很强大,国民都很有钱</a> <a href="" class="du">总为浮云能蔽日,长安不见使人愁</a> <img src="http://www.baidu.com/meinv.jpg" alt="" /> </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 href="http://www.126.com" alt="qi">岐王宅里寻常见,崔九堂前几度闻,正是江南好风景,落花时节又逢君</a></li> <li><a href="http://www.sina.com" class="du">杜甫</a></li> <li><a href="http://www.dudu.com" class="du">杜牧</a></li> <li><b>杜小月</b></li> <li><i>度蜜月</i></li> <li><a href="http://www.haha.com" id="feng">凤凰台上凤凰游,凤去台空江自流,吴宫花草埋幽径,晋代衣冠成古丘</a></li> </ul> </div> </body> </html>
开始测试:
from lxml import etree # pip install lxml # 本地文件 tree = etree.parse('test01.html') # 如果是网络文件,应使用etree.HTML() # 1.取出class为song的div标签下的所有文本内容 ret01 = tree.xpath('//div[@class="song"]//text()') # //text() 表示取出某个标签下文本内容和所有子标签下的文本内容,如果存在文本,则返回的是单个元素的列表 # 2.取出class为tang的div下的直系子标签ul下的直系子标签第二个li下的直系子标签a标签下的内容 ret02 = tree.xpath('//div[@class="tang"]/ul/li[2]/a/text()') # /text() 表示取出某个标签下的文本内容,如果存在文本,则返回的是单个或多个元素的文本 # li[2] 表示取第2个li标签 # 3.取出href属性值为空 且 class属性值为du的a标签内的文本内容 ret03 = tree.xpath('//a[@href="" and @class="du"]/text()') # 逻辑运算:and # 4.取出class包含 ta 的div标签下的所有文本内容(包括子孙标签) ret04 = tree.xpath('//div[contains(@class, "ta")]//text()') ret05 = tree.xpath('//div[starts-with(@class, "ta")]//text()') # 模糊匹配:contains(@class, "ta") 或 starts-with(@class, "ta") # 5.取出class为tang的div标签下的任意标签下li标签(第2个)下的a标签内href属性的值 ret06 = tree.xpath('//div[@class="tang"]//li[2]/a/@href') # 6. / 开头的,表示最外层的标签 ret07 = tree.xpath('/html/body/div[@class="tang"]//text()') # 定位所有class为tang的div tree.xpath('//div[@class="tang"]') # 7. .// 表示从当前标签开始找 ret08 = tree.xpath('.//a/text()') > # 8. | 表示或者 ret08 = tree.xpath('//div[@class="song"] | //div[@class="tang"]')
你还可以在浏览器中安装xpaht插件,以实现在浏览器中对xpath表达式进行验证,以及通过html元素获得xpath表达式。
实例:下载煎蛋网中的图片
import os import base64 import requests from lxml import etree import urllib.request # 使用其来快速保存内容 from fake_useragent import UserAgent # 随机UA url = 'http://jandan.net/pic/page-%s#comments' # 煎蛋网 headers = 'User-Agent': UserAgent(use_cache_server=False).random page_text = requests.get(url=url % 1, headers=headers) # 爬取第1页的内容 page_text.encoding = 'utf-8' content = page_text.text # 查看页面源码:发现所有图片的src值都是一样的。 # 简单观察会发现每张图片加载都是通过jandan_load_img(this)这个js函数实现的。 # 在该函数后面还有一个class值为img-hash的标签,里面存储的是一组hash值,该值就是加密后的img地址 # 加密就是通过js函数实现的,所以分析js函数,获知加密方式,然后进行解密。 # 通过抓包工具抓取起始url的数据包,在数据包中全局搜索js函数名(jandan_load_img),然后分析该函数实现加密的方式。 # 在该js函数中发现有一个方法调用,该方法就是加密方式,对该方法进行搜索 # 搜索到的方法中会发现base64和md5等字样,md5是不可逆的所以优先考虑使用base64解密 tree = etree.HTML(content) # 获取所有加密的图片地址 img_code_list = tree.xpath('//span[@class="img-hash"]/text()') # 开始解密 img_url_list = [] for code_url in img_code_list: img_url = 'http:' + base64.b64decode(code_url).decode() img_url_list.append(img_url) # 保存图片 dirname = '煎蛋图' os.mkdir(dirname) for url in img_url_list: file_name = url.split('/')[-1] file_path = os.path.join(dirname, file_name) urllib.request.urlretrieve(url=url, filename=file_path) print(f'file_path已保存')
BeautifulSoup解析
待
原文: http://106.13.73.98/__/132/
以上是关于网络爬虫的三种解析方式 -- 2019-08-08 18:01:21的主要内容,如果未能解决你的问题,请参考以下文章