python爬虫(三)xpath与lxml

XPath

XPath是一种在xml中查找信息的语言,可以用来在xml文档中对元素和属性进行遍历。
XPath使用路径表达式在xml文档中选取节点,这里注意需要逐级表现要选取节点的父子关系。

XPath符号

  • nodename 选取此节点的所有子节点
  • / 从根节点选取
  • // 从匹配选择的当前节点文档中,而不考虑他们位置
  • . 选取当前节点。
  • .. 选取当前节点的父节点
  • @ 选取属性
  • * 表示通配
  • | 连接多个表达式,做并集操作

XPath路径表达

  • bookstore 选取bookstore元素的所有子节点。
  • /bookstore 选取根元素bookstore。
    • 假如路径起始于正斜杠 。注释:假如路径起始于正斜杠 。注释:假如路径起始于正斜杠 。注释:假如路径起始于正斜杠 ( / ( / ),则此路径始 ,则此路径始 终代表到某元素的绝对路径!
  • bookstore/book 选取bookstore子元素中所有book元素。
  • //book选取所有book元素,而不管它们在文档中的位置。
  • bookstore//book bookstore 选择bookstore元素的后代中所有book元素,而不管它们位于bookstore下的什么位置
  • //@auth 选取所有名为auth的属性

XPath谓语

谓语表达了针对该层级节点的筛选条件,常见谓语如下

  • /book[2] 表示在该级选取第二个book节点
  • /book[last()] 表示在该级选取最后一个book节点
  • /book[position()<5] 表示在该级选取前四个book节点
  • /book[@auth] 表示在该级选取所有拥有auth属性的book节点
  • /book[@auth="buka"] 表示在该级选取所有auth属性值为buka的book节点
  • /book[price>35.00] 表示在该级选取price子元素的值大于35的book节点

lxml库

lxml是一个用于灵活处理xml格式数据的库,此处可以用来帮助做网页解析。
lxml用来做网页解析的时候最常用的是其中的etree对象(lxml库需保持在3.8版本以下)

简单页面解析

import requests
from lxml import etree

res = requests.get('https://www.baidu.com/').text
# 使用etree.HTML()完成标签优化,准备解析
html = etree.HTML(res)
print(html.xpath('string(//*[@id="u1"]/a[@name="tj_trtieba"]/@href)'))

页面内容抓取

import requests
from lxml import etree
from urllib.parse import urljoin

# 本例实际使用requests+lxml来抓取python百例信息
url = 'http://www.runoob.com/python/python-100-examples.html'
res = requests.get(url).text
html = etree.HTML(res)
li_list = html.xpath('//*[@id="content"]/ul/li')
exam_list = []
for li in li_list:
    href = li.xpath('a/@href')
    exam_url = urljoin(url, href[0])
    # 此处使用requests默认解析会乱码,需要抓取正文手动解码
    exam_res = requests.get(exam_url).content.decode('utf-8')
    exam_html = etree.HTML(exam_res)
    title = exam_html.xpath('string(//*[@id="content"]/h1)')
    quest = exam_html.xpath('string(//*[@id="content"]/p[2])')
    analyse = exam_html.xpath('string(//*[@id="content"]/p[3])')
    code = exam_html.xpath('string(//div[@class="hl-main"]|//pre[@class="prettyprint prettyprinted"])')
    exam_dict = {
        'title': title,
        'quest': quest,
        'analyse': analyse,
        'code': code
    }
    print(exam_dict)
    exam_list.append(exam_dict)

import pandas

df = pandas.DataFrame(exam_list, columns=['title', 'quest', 'analyse', 'code'])
df.to_csv('exam.csv')

猜你喜欢

转载自blog.csdn.net/bkk854762363/article/details/78925910