Lxml 和 Xpath 学习:
Lxml库:Lxml库是基于libxml2 这一个XML 解析库的Python 封装。该模块使用C语言编写,解析速度比BeautifulSoup 更快。Lxml库使用Xpath语法解析定位网页数据。
1.Lxml库解析网页数据快,还有一个非常实用的功能就是自动修正 HTML 代码。
2.Lxml 除了直接读取字符串,还支持 从本地文件中提取内容,例如本地编辑的hml代码
3. 我们通常 用 requests
库获取 HTML 文件,然后用Lxml
库 来解析HTML 文件!
Xpath:
Xpath 是一门在 XML 文档中查找信息的语言,对 HTML 文档也有很好的支持。
XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者step 来选的
表达式 | 描述 |
---|
nodename | 选取此节点的所有节点 |
/ | 从根节点选取 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 |
. | 选取当前节点 |
… | 选取当前节点的父节点 |
@ | 选取属性 |
比如下面的示例:
路径表达式 | 结果 |
---|
user_database | 选取元素user_database的所有子节点 |
/user_database | 选取根元素user_database。注释:假如路径起始于正斜杠(/) ,则此路径始终代表到某元素的绝对路径 |
user_database/user | 选取属于user_database的子元素的所有user元素 |
//user | 选取所有user子元素,而不管它们在文档中的位置 |
user_database//user | 选取属于user_database元素的后代的所有user元素,而不管它们位于user_database之下的什么位置 |
//@attribute | 选取名为 attribute 的所有属性 |
Xpath 语法中的谓语用来查找某个特定的节点或者包含某个指定值的节点,谓语被嵌在方括号中。常见的谓语如下表所示:
路径表达式 | 结果 |
---|
/user_database/user[1] | 选取属于user_database子元素的第一个user元素 |
//li[@attribute] | 选取所有拥有名为 attribute 属性的 li 元素 |
//li[ @attribute = ‘red’ ] | 选取所有 li 元素,且这些元素拥有值为 red 的 attribute 属性 |
Xpath 中也可以使用 通配符来选取位置的元素,常用的就是 *
通配符,它可以匹配任何元素节点
Xpath 实战中的使用技巧:
(1). 鼠标光标定位到想要提取的数据位置,右击,从弹出的快捷菜单中选择 检查
命令。
(2). 在网页源代码中右击所选元素。
(3). 从弹出的快捷菜单中选择 Copy Xpath 命令
今天的学习任务:使用xpath提取丁香园论坛的回复内容。
代码如下:
import requests
from lxml import etree
import time
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) '
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
'Cookie': 'DXY_USER_GROUP=3; __auc=eee9c4a71693eb8cd2ef89b9900; _ga=GA1.2.751487223.1551535495;'
' _gid=GA1.2.1641632121.1551617165; JUTE_SESSION_ID=e4e8ab95-3c81-4f56-ac11-bdc1d4b3b37b;'
' JUTE_TOKEN=41685543-bbf4-44c9-b9d9-ba28f2712b7a; __utmc=1; JUTE_BBS_DATA=c1cb8c65603c6a2'
'20551ceab04f950ea449f2bb972c54c673b036cdc6892e8151bab230aaba331959d6ec710f86d0fb7ab76244eb'
'32d55065c98b7aeecef3a838bfb19bd58076227705076b209cab73a; cms_token=2a8c6db3-9d58-429c-9239-'
'04618cacaa01; CMSSESSIONID=BB1CBEC6D9C8C97140F4C31AAC3E69AC-n2; __utma=1.751487223.155153549'
'5.1551694970.1551704453.4; __utmz=1.1551704453.4.2.utmcsr=auth.dxy.cn|utmccn=(referral)|utmc'
'md=referral|utmcct=/; JUTE_SESSION=9f1610890ef72c3e0d0cf0ee0e36c505ed176e2b37977b7b449a37658'
'aac5d4e11c61882b068e341ef9ff3b29378d4401b7648b4cd5b19f7cb9a308aac209b94706e5832db02c563; __u'
'tmb=1.9.7.1551706830996'
}
def get_detail_info(url):
"""
:param url:
:return:
"""
data = []
data_list = []
html = requests.get(url, headers=headers)
reply = etree.HTML(html.text)
result_name = reply.xpath('//div[@class="auth"]/a/text()')
result_data = reply.xpath('//td[@class="postbody"]/text()')
for i in range(0, int(len(result_name))):
data.append(result_name[i] + "++++++++" + result_data[i])
for i in data:
new = i.replace("\n", "").replace("\t", "").replace(" ", "")
data_list.append(new)
print(data_list)
if __name__ == '__main__':
get_detail_info("http://www.dxy.cn/bbs/thread/626626#626626")
time.sleep(4)
输出结果如下:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/9f15c9e3f96cbd35a3fadfd8174d96ba.png)
今天工作比较忙,暂时就先写成这样,具体的我下去在整理一下,坚持每天记录!