通过urllib,我们可以访问目标服务器,从目标服务器中获得网页源码。但是获得的内容需要通过进一步解析才能得到我们需要的数据
常用的解析工具:xpath,beautifulsoup,jsonpath
xpath
xpath用来获取网页中的部分数据
安装xpath
链接:https://pan.baidu.com/s/1KeXInPcU8wGxrOKocTKxbA?pwd=5tb1
提取码:5tb1
打开上面的链接,找到xpath.zip,将其拖拽到浏览器中的拓展程序,并启动它
重启浏览器,使得xpath生效
快捷键ctrl+shift+x出现小黑框,说明安装成功
安装lxml
lxml必须安装在项目所在python路径下,查看项目所在的python路径的方法:打开pycharm-file-settings
win+R进入windows命令行,进入到python所在的文件夹下面:(dir命令用来查看文件夹下面的所有文件信息)
然后进入scripts文件夹
使用国内源下载lxml
pip install lxml -i https://pypi.douban.com/simple
检验lxml
解析本地文件:
首先创建一个html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
<li>北京</li>
<li>上海</li>
<li>深圳</li>
<li>武汉</li>
</ul>
<ul>
<li>大连</li>
<li>锦州</li>
<li>沈阳</li>
</ul>
</body>
</html>
然后开始检验:
from lxml import etree
# xpath解析
# (1)本地文件 etree.xparse
# (2)服务器响应的数据 response.read().decode('utf-8') etree.html
tree = etree.parse('爬虫_解析_xpath的基本使用.html')
print(tree)
结果如下:
报错的原因是lxml解析的元素必须一一对应,像是
而我们的meta元素却没有结束符,只需要做如下修改:
修改之后为:
运行结果如下:
xpath基本语法(解析本地文件)
1 路径查询:
//表示在页面中所有的标签
/表示直接子节点
比如下面的例子(html文件同上):
这个例子中的//li表示所有的li标签,输入//ul/li也是一样的结果,即所有ul标签下的li标签2 谓词查询
# li_list = tree.xpath('//ul/li[@id]') # 输出所有有id属性的标签 # li_list = tree.xpath('//ul/li[@id]/text()') # 将输出标签表示为明文 # li_list = tree.xpath('//ul/li[@id = "l1"]/text()') # 输出id为l1的标签
3 属性查询
用来输出元素的属性li_list = tree.xpath('//ul/li[@id = "l1"]/@class') # 输出id为l1的属性值
4 模糊查询
li_list = tree.xpath('//ul/li[contains(@id,"l")]/text()') # id中包含l的li标签 li_list = tree.xpath('//ul/li[starts-with(@id, "c")]/text()') # id中以c开头的li标签
5 逻辑运算
与:and
或:|li_list = tree.xpath('//ul/li[@id="l1" and @class="c1"]/text()') # 查询id为l1且class为c1的 li_list = tree.xpath('//ul/li[@id="l1"]/text() | //ul/li[@id="l2"]/text()')
完整的代码和html文件如下:
from lxml import etree # xpath解析 # (1)本地文件 etree.xparse # (2)服务器响应的数据 response.read().decode('utf-8') etree.html # xpath解析本地文件 tree = etree.parse('爬虫_解析_xpath的基本使用.html') # tree.xpath('xpath路径') # *******路径查询**************************** # li_list = tree.xpath('//li') # li_list = tree.xpath('//body/ul/li') # *******谓词查询**************************** # li_list = tree.xpath('//ul/li[@id]') # 输出所有有id属性的标签 # li_list = tree.xpath('//ul/li[@id]/text()') # 将输出标签表示为明文 # li_list = tree.xpath('//ul/li[@id = "l1"]/text()') # 输出id为l1的标签 # ********属性查询*************************** # li_list = tree.xpath('//ul/li[@id = "l1"]/@class') # 输出id为l1的属性值 # ********模糊查询******************* # li_list = tree.xpath('//ul/li[contains(@id,"l")]/text()') # id中包含l的li标签 # li_list = tree.xpath('//ul/li[starts-with(@id, "c")]/text()') # id中以c开头的li标签 # ********逻辑运算******************** # li_list = tree.xpath('//ul/li[@id="l1" and @class="c1"]/text()') # 查询id为l1且class为c1的 li_list = tree.xpath('//ul/li[@id="l1"]/text() | //ul/li[@id="l2"]/text()') print(li_list) print(len(li_list))
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <title>Title</title> </head> <body> <ul> <li id="l1" class = "c1">北京</li> <li id="l2">上海</li> <li id = "c3">深圳</li> <li id = "c4">武汉</li> </ul> <ul> <li>大连</li> <li>锦州</li> <li>沈阳</li> </ul> </body> </html>
解析服务器响应文件
需求:打开百度,解析出百度一下这四个字
按键ctrl + shift + x打开xpath,找到正确的检查条件:
解析步骤如下:
- 获取网页源码
- 解析服务器响应文件(etree.HTML)
# 获取网页源码 # 解析服务器响应文件 etree.HTML # 打印 ############################获取网页源码################################################################# import urllib.request url = 'https://www.baidu.com/' headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36' } request = urllib.request.Request(url = url, headers = headers) response = urllib.request.urlopen(request) content = response.read().decode('utf-8') # print(content) ##############################解析网页源码,获取我们想要的数据############################################################## from lxml import etree tree = etree.HTML(content) # xpath解析的结果是一个列表 result = tree.xpath('//input[@id="su"]/@value')[0] print(result)