Xpath提取数据

一、什么是Xpath?

XML 指可扩展标记语言(EXtensible Markup Language)
XML 是一种标记语言,很类似 HTML
XML 的设计宗旨是传输数据,而非显示数据
XML 的标签需要我们自行定义。
XML 被设计为具有自我描述性。
XML 是 W3C 的推荐标准
W3School 官方文档:http://www.w3school.com.cn/xml/index.asp

XML 和 HTML 的区别:

二、xpath中的节点关系

1、xpath中的节点关系

父节点

每个元素以及属性都有一个父。
下面是一个简单 XML 例子中,book 元素是 title、author、year 以及 p

子节点

元素节点可有零个、一个或多个子。
在下面的例子中,title、author、year 以及 price 元素都是 book 元素的子:

同胞节点

拥有相同的父的节点
在下面的例子中,title、author、year 以及 price 元素都是同胞:

先辈节点

某节点的父、父的父,等等。
在下面的例子中,title 元素的先辈是 book 元素和 bookstore 元素

后辈节点

某个节点的子,子的子,等等。
在下面的例子中,bookstore 的后代是 book、title、author、year 以及 price 元素:

三、xpath的用法

1、选取节点

XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我
们在常规的电脑文件系统中看到的表达式非常相似。

了最常用的路径表达式:

id  获取id 的属性值

starts-with 顾名思义,匹配一个属性开始位置的关键字  -- 模糊定位

contains 匹配一个属性值中包含的字符串  -- 模糊定位

text()  函数文本定位

last()  函数位置定位

2、语法

在python中用xpath时,需要用到lxml模块,这是python的第三方模块,可以通过命令 pip insall lxml下载该模块

或者也可以在pycharm中的setting的project Interpreter 里面进行下载

# 引入模块
from  lxml import  etree

# 使用etree.HTML(text),将文字信息转化成一个树形结构
tree = etree.HTML(text) #将文档生成一棵树

# 之后就可以通过生成的文档树 tree 来查找节点

2、具体案例

(1) 爬取腾讯招聘

爬取腾讯招聘网页中所有python的北京职位,要求爬出对应的职位名称,职位类别,职位人数,职位地址及职位招聘时间

需要注意的是,在发起网络请求时,需要在请求头部,也就是request header 中加入 User-Agent 及对应的浏览器表示,腾讯招聘通过此项数据来进行反爬虫,由于我们使用的是程序,不具备此项,所以需要加入此项来伪装成一个浏览器。

还需要注意的是,原网页中一些节点在我们进行爬取之后在本地生成的文件中,可能不会显示,所以进行选取节点时,要根据生成的本地文件的节点来进行节点选取。

还需要注意的是:爬取一个表格中所有数据时,最好选取到这几项数据所在的父节点,进行循环遍历提取,如果在数据的上面几层几点进行遍历提取,可能会由于数据缺失,造成遍历时,索引错误

具体代码:

# 分析接口
# 第一页: 'https://hr.tencent.com/position.php?lid=&tid=&keywords=python&start=0#a'
# 第二页: 'https://hr.tencent.com/position.php?lid=&tid=&keywords=python&start=10#a'
# 第三页: 'https://hr.tencent.com/position.php?lid=&tid=&keywords=python&start=20#a'
# 第n页:start = (n-1)*10

import requests
from lxml import etree


# 定义一个函数,用来判断空
def getDataFormList(temp_list):
    if len(temp_list) > 0:
        return temp_list[0]
    else:
        return ''


page = 1
# for page in range(1, 59, 1)
while True:
    # 生成url
    url = 'https://hr.tencent.com/position.php?lid=&tid=&keywords=python&start=' + str((page - 1) * 10)

    print('第%s页网址'%(page),url)
    # 由于服务器可能使用了反爬虫策略,所以我们应该将自己伪装成一个浏览器
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
    }

    # 网络访问
    response = requests.get(url, headers=headers)
    # with open('python.html', 'w', encoding='utf-8') as fp:
    #     fp.write(response.text)

    # 数据提取
    tree = etree.HTML(response.text)
    tr_list = tree.xpath('//table[@class="tablelist"]/tr')
    # 由于存在表头和表尾,所以去掉表头和表尾的tr标签节点
    tr_list.pop(0)  # 删除表头
    tr_list.pop()  # 删除表尾
    # 剩下的是10个职位数据信息
    if len(tr_list) == 0:
        print('超出页码范围')
        break

    for tr in tr_list:
        td_list = tr.xpath('./td')

        # 需要职位名称,类别,人数,地点,发布时间
        # 名称
        job_name_list = td_list[0].xpath('./a/text()')
        job_name = getDataFormList(job_name_list)
        # print(job_name)
        # 类别
        job_type_list = td_list[1].xpath('./text()')
        job_type = getDataFormList(job_type_list)
        # 人数
        job_number_list = td_list[2].xpath('./text()')
        job_number = getDataFormList(job_number_list)
        # 地点
        job_addr_list = td_list[3].xpath('./text()')
        job_addr = getDataFormList(job_addr_list)
        # 发布时间
        job_time_list = td_list[4].xpath('./text()')
        job_time = getDataFormList(job_time_list)

    print('第%s页数据'%(page),job_name, job_type, job_number, job_addr, job_time)
    page += 1
    # print(tr_list)
    # print(len(tr_list))

运行结果:

(2)爬取扇贝网

爬取 https://www.shanbay.com/wordlist/110521/232414/?page 中三页所有的单词信息

具体代码

import requests
from lxml import etree
base_url = 'https://www.shanbay.com/wordlist/110521/232414/?page=%d'

# 判空
def getDataformList(temple_list):
    if len(temple_list)>0:
        return temple_list[0]
    else:
        return ''

for page in range(1, 4, 1):
    url = base_url % (page)
    print(url)
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'

    }
    response = requests.get(url, headers=headers)
    # with open('shanbei.html', 'w', encoding=response.encoding) as fp:
    #     fp.write(response.text)
    tree = etree.HTML(response.text)
    tr_list = tree.xpath('//div[@class="span8"]/table/tbody/tr[@class="row"]')
    # print(tr_list)
    for tr in tr_list:

        # 英文
        English_list = tr.xpath('.//td[@class="span2"]/strong/text()')
        English = getDataformList(English_list)


        # 汉语
        Chinese_list = tr.xpath('.//td[@class="span10"]/text()')
        Chinese = getDataformList(Chinese_list).replace('\n','')

        print(English+':'+Chinese)
        with open('shanbei.txt','a',encoding=response.encoding) as fp:
            fp.write(English+'\t'+Chinese+'\n')

运行结果;

3、拼接路径

拼接路径用到了python自带的urllib模块

具体用法如下:

from urllib import request
# request 用法
# request.urljoin(base= '请求路径', url='相对路径' )
base_url = 'http://www.langlang2017.com/index.html'
src = 'fengjing,png'
full_url = request.urljoin(base_url,src)
print(full_url)

运行结果:

 

 

 

 

 


版权声明:本文为weixin_44239541原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。