用lxml跑一个简单的流程 1.0版本

思路

  1. 用request请求需要访问的路径
  2. 选择器选择,用什么形式打印
  3. 请求的路径,找到需要打印东西(标签)
  4. 循环打印
  5. 如果级联,在第一次打印的基础上进行再次请求,获取页面,继续访问请求
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进行处理)

  1. 两列数据,第一列数据用key表示出来,第二列数据用values表示,组成一个新的字典格式
  2. 如果values是嵌套的,嵌套的标签用双斜杠标签
  3. 如果同级标签,不止一个并列的p标签,遍历出来,然后用空格相链接,拼接成一个新的values
  4. 用zip拉链函数把key-values拼接起来
  5. 在外面再嵌套一层字典,用标题和内容再次进行字典封装
  6. 遍历,用了两层字典,遍历也需要两次,第一次遍历标题,第二次遍历第一个字典的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版本

替换掉重复的部分

  1. keys, cols的xpath地址有很多重复的,我们可以用一个变量替换掉他们
  2. 这里需要注意的是,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]

你可能感兴趣的:(lxml)