目标
http://www.zuihaodaxue.com/zuihaodaxuepaiming2019.html
爬取中国大学2019的排名信息,爬取‘排名’,‘学校名’,‘省份’,‘总分’,这四个字段信息
我们代码与 ‘bs4 提取’ 章节,类似,只有部分需要修改
环境配置
需要用到的库 lxml
命令行 cmd 输入命令,pip install lxml ,完成安装即可
请求网页
def get_html(url):
'''
获得 HTML
'''
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/53\
7.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
response.encoding = 'utf-8'
return response.text
else:
return
我们看到比上一章代码,多了一个 response.encoding = 'utf-8'
这个的意思是说,把响应的结果的 html 源码的编码格式设置成 utf-8,不这样做的话,我们提取到的数据中如果有中文的,那显示就会是乱码
分析数据
右键-检查,查看元素如下图:
可以看到,我们所需要的数据是画红线部分的数据,我们把它折叠起来,tr 标签左边有个小箭头,点击折叠,如图:
折叠后我们可以看到,高亮条对应的部分,意思是每一条‘排名’‘学校名’‘省份’‘总分’都对应一个 <tr class="alt">...</tr> 标签
我们拉到网页最底部,可以看到有 549 个学校,就是说这样的标签有 549 条,我们需要先提取它们,再从每一条标签提取信息
提取数据
html = etree.HTML(html)
# 提取所有的大学标签信息
ls = html.xpath('//tr[@class="alt"]')
for info in ls:
# 排名
rank = info.xpath('./td[1]/text()')[0]
# 学校名
name = info.xpath('./td[2]/div/text()')[0]
# 省份
province = info.xpath('./td[3]/text()')[0]
# 总分
score = info.xpath('./td[4]/text()')[0]
data = {
'排名' : rank,
'校名' : name,
'省份' : province,
'总分' : score,
}
print(data)
我们看到这里的解析有变成了 html = etree.HTML(html)
这是使用 lxml 解析 html 的写法
提取所有的学校信息的标签,就是上面说的 549 条标签,使用 xpath 方法选择标签在 html 源码里的路径,// 是选择此 html 源码里所有 tr 标签并且 class 属性为 alt 的标签
ls = html.xpath('//tr[@class="alt"]')
提权取完 549 条标签后,xpath 返回的是列表,我们需要一次循环列表,循环每一个标签从中提取出每个数据,我们观察每一条标签下的子节点,如图,有很多 td 标签,从上往下依次是 1 号,2 号。。。。td 标签,2 号 td 下面还有节点,所以在 2 号 td 的写法还需要选取它的子节点
所以写法如下
‘.’ 代表当前节点,就是对应的每次循环的这个标签的节点
‘/’ 依次选择路径
text() 获得标签中的文本信息,就是我们的实际数据
由于 xpath 返回列表,所以我们需要取第一个结果 [0]
# 排名
rank = info.xpath('./td[1]/text()')[0]
# 学校名
name = info.xpath('./td[2]/div/text()')[0]
# 省份
province = info.xpath('./td[3]/text()')[0]
# 总分
score = info.xpath('./td[4]/text()')[0]
END
到这里,我们就完成了一次 lxml 提取,xpath 这里只提到了 / , //,. 这三个用法,更多的用法,可以参考:
https://www.runoob.com/xpath/xpath-syntax.html
https://blog.csdn.net/zjkpy_5/article/details/81041815
完整代码
import requests
import time
from lxml import etree
def get_html(url):
'''
获得 HTML
'''
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/53\
7.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
response.encoding = 'utf-8'
return response.text
else:
return
def get_infos(html):
'''
提取数据
'''
html = etree.HTML(html)
# 提取所有的大学标签信息
ls = html.xpath('//tr[@class="alt"]')
for info in ls:
# 排名
rank = info.xpath('./td[1]/text()')[0]
# 学校名
name = info.xpath('./td[2]/div/text()')[0]
# 省份
province = info.xpath('./td[3]/text()')[0]
# 总分
score = info.xpath('./td[4]/text()')[0]
data = {
'排名' : rank,
'校名' : name,
'省份' : province,
'总分' : score,
}
print(data)
def main():
'''
主接口
'''
url = 'http://www.zuihaodaxue.com/zuihaodaxuepaiming2019.html'
html = get_html(url)
get_infos(html)
time.sleep(1)
if __name__ == '__main__':
main()
{'排名': '1', '校名': '清华大学', '省份': '北京', '总分': '94.6'}
{'排名': '2', '校名': '北京大学', '省份': '北京', '总分': '76.5'}
{'排名': '3', '校名': '浙江大学', '省份': '浙江', '总分': '72.9'}
{'排名': '4', '校名': '上海交通大学', '省份': '上海', '总分': '72.1'}
....