用lxml跑一个简单的流程 2.0版本
程序员文章站
2022-06-06 08:44:32
...
用函数将代码优化
- 将代码划分为三个函数(模块),第一个函数请求根路径
- 第二个函数,请求二级页面,遍历出大学的详细信息
- 第三个函数,主函数,控制整个程序的运行,
- 在主函数里,先获取请求页面的路径,然后link出一级页面,最后,把这个一级页面的路径用parse_university循环出他的子信息。
需要注意的是,不能把路径直接传入fetch函数,因为在主函数里,每一次循环二级页面都需要访问一级页面,重新遍历一级页面fetch函数的值
import lxml.etree
import requests
START_URL= 'http://qianmu.iguye.com/2018USNEWS世界大学排名'
def fetch(url):
START_URL = 'http://qianmu.iguye.com/2018USNEWS世界大学排名'
r = requests.get(url)
# 服务器出错信息
r.raise_for_status()
r.encoding='utf-8'
return r.text
# 负责将每一个大学的子信息都遍历出来(二级遍历)
def parse_university(html):
selector = lxml.etree.HTML(html)
title = selector.xpath('//*[@id="wikiContent"]/h1/text()')[0]
infobox = selector.xpath('//div[@class="infobox"]')[0]
# p//text()双斜杠,表示把隐藏的也显示出来
keys = infobox.xpath('./table//tr/td[1]/p//text()')
cols = infobox.xpath('./table//tr/td[2]')
# 把values的内容便利出来,用空格链接起来
values = [''.join(col.xpath('.//text()')) for col in cols]
info = {title: dict(zip(keys, values))}
for name, properties in info.items():
print(name)
for k, v in properties.items():
print('%s:%s' % (k, v))
print('-' * 30)
if __name__ == '__main__':
# 获取请求页面的路径
selector = lxml.etree.HTML(fetch(START_URL))
# 获取一级页面的内容(标签)
links = selector.xpath('//*[@id="content"]/table/tbody/tr/td/a/@href')
# 遍历二级页面,将需要的每一条大学数据遍历出来(一级遍历)
for link in links:
parse_university(fetch(link))
2.1 按顺序排列
字典是无序的,实现按顺序排列,将字典换成列表就行了
1. 在二级页面循环的时候,每次都先把标题(这里是大学名)打印出来
2. 循环大学信息的时候,直接用列表的形式循环出keys和values
def parse_university(html):
selector = lxml.etree.HTML(html)
title = selector.xpath('//*[@id="wikiContent"]/h1/text()')[0]
# 打印大学名
print(title)
infobox = selector.xpath('//div[@class="infobox"]')[0]
keys = infobox.xpath('./table//tr/td[1]/p//text()')
cols = infobox.xpath('./table//tr/td[2]')
values = [''.join(col.xpath('.//text()')) for col in cols]
# 用列表的形式循环出keys, values
for k, v in zip(keys, values):
print('%s:%s'%(k, v))
print('-' * 30)