思路
- 用request请求需要访问的路径
- 选择器选择,用什么形式打印
- 请求的路径,找到需要打印东西(标签)
- 循环打印
- 如果级联,在第一次打印的基础上进行再次请求,获取页面,继续访问请求
import lxml.etree
import requests
# 获取地址IP
START_URL= 'http://qianmu.iguye.com/2018USNEWS世界大学排名'
# 用request抓取页面
r = requests.get(START_URL)
r.encoding = 'utf-8'
# 选择器选择,以什么样的形式打印,r.text以文本的形式打印
selector = lxml.etree.HTML(r.text)
# 请求的xpath路径,定义打印的具体内容
links = selector.xpath('//*[@id="content"]/table/tbody/tr/td/a/@href')
for link in links:
print(link)
#二级打印,在第一个抓取的页面基础上再次请求
r = requests.get(link)
r.encoding='utf-8'
# 选择器选择
selector = lxml.etree.HTML(r.text)
# text()获取p标签后面的文本
info = selector.xpath('//div[@class="infobox"]/table//tr/td/p/text()')
for i in info:
print(i)
1.1版本
把数据用字典的形式表示出来(对遍历的info进行处理)
- 两列数据,第一列数据用key表示出来,第二列数据用values表示,组成一个新的字典格式
- 如果values是嵌套的,嵌套的标签用双斜杠标签
- 如果同级标签,不止一个并列的p标签,遍历出来,然后用空格相链接,拼接成一个新的values
- 用zip拉链函数把key-values拼接起来
- 在外面再嵌套一层字典,用标题和内容再次进行字典封装
- 遍历,用了两层字典,遍历也需要两次,第一次遍历标题,第二次遍历第一个字典的values。
for link in links:
print(link)
r = requests.get(link)
r.encoding='utf-8'
selector = lxml.etree.HTML(r.text)
# 标题信息,xpath是列表,所以每次取他的第一个
title = selector.xpath('//*[@id="wikiContent"]/h1/text()')[0]
# 第一列数据,p//text()双斜杠,表示把隐藏的也显示出来
keys = selector.xpath('//div[@class="infobox"]/table//tr/td[1]/p/text()')
# 第二列数据
cols = selector.xpath('//div[@class="infobox"]/table//tr/td[2]')
# 拼接几个并列的p标签
values = [''.join(col.xpath('.//text()'))for col in cols]
# zip拉链函数,把两列数据连接在一起,组成新的info
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)
1.2版本
替换掉重复的部分
- keys, cols的xpath地址有很多重复的,我们可以用一个变量替换掉他们
- 这里需要注意的是,xpath是列表类型,所以命名的新变量需要加索引
title = selector.xpath('//*[@id="wikiContent"]/h1/text()')[0]
# 用infobox替换重复的路径
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]