爬虫-xpath和lxml模块

1. xpath介绍

1.1 基本概念

XPath(XML Path Language)是⼀种XML的查询语⾔,他能在XML树状 结构中寻找节点。XPath ⽤于在 XML ⽂档中通过元素和属性进⾏导航。
xml是⼀种标记语法的⽂本格式,xpath可以⽅便的定位xml中的元素和其中 的属性值。lxml是python中的⼀个包,这个包中包含了将html⽂本转成xml 对象,和对对象执⾏xpath的功能 。

1.2 结点的关系

xml_content = ''' 
 <bookstore> 
 <book> 
 <title lang='eng'>Harry Potter</title>
 <author>K.Rowing</author> 
 <year>2005</year> 
 <price>29<price> 
 </book> 
 </bookstore> 
         ''' 

⽗(Parent) book元素是title、author、year、price元素的⽗
⼦(Children) title、author、year、price都是book元素的⼦
同胞(Sibling) title、author、year、price都是同胞
先辈(Ancestor) title元素的先辈是 book元素和bookstore元素

2. 基本使⽤

2.1 工具安装

chrome插件XPath Helper的下载与安装
1.下载xpath-helper.crx
2.安装
chrome浏览器输入:chrome://extensions/
在这里插入图片描述
直接将chrome_Xpath_v2.0.2.crx拖动至该扩展程序页面 ;
如果安装失败,弹框提示 无法从该网站添加应用、扩展程序和用户脚本 ,则打开开发者模式,将crx文件(直接或后缀修改为rar)并解压成文件夹,点击开发者模式的加载已解压的扩展程序,选择解压后的文件夹,点击确定,安装成功。
3.使用
打开浏览器,按住Ctr+Shift+X;
在这里插入图片描述
选择元素,如下图所示:
右键“Copy XPath”在这里插入图片描述
在这里插入图片描述
查找某个特定的节点或者包含某个指定的值的节点
在这里插入图片描述

2.2 模块的使⽤

在Python中,我们安装lxml库来使⽤XPath 技术.
lxml 是 ⼀个HTML/XML的解析器,主要的功能是如何解析和提取HTML/XML
数据利⽤etree.HTML,将字符串转化为Element对象.
lxml python 官⽅⽂档:http://lxml.de/index.html
可使⽤ pip 安装:pip install lxml
lxml 可以⾃动修正 html 代码

 import lxml
from lxml import etree
# 第一个是将html/xml字符串转化为element对象
# 第二个是element对象可以转换为字符串或者是二进制类型的数据
wb_data = """
        <div>
            <ul>
                 <li class="item-0"><a href="link1.html">first item</a></li>
                 <li class="item-1"><a href="link2.html">second item</a></li>
                 <li class="item-inactive"><a href="link3.html">third item</a></li>
                 <li class="item-1"><a href="link4.html">fourth item</a></li>
                 <li class="item-0"><a href="link5.html">fifth item</a>
             </ul>
         </div>
        """
        html_element = etree.HTML(wb_data)
        print(html_element)
        result = etree.tostring(html_element)
r = result.decode()
 print(type(r),r)
 # 获取li标签下面a标签的href
 links = html_element.xpath('//li/a/@href')
print(links)
# 获取li标签下a标签的内容
result = html_element.xpath('//li/a/text()')
print(result)
# 我想把这些数据组合到一个字典当中 例如{'href':'link1.html','title':'first item'}
for link in links:
    d = {}
    d['href'] = link
    # 拿到下标索引值
 print(links.index(link))
  d['title'] = result[links.index(link)]
  print(d)
# 需求:爬取电影的名字 评分 引言 详情页的url,每一页都爬取并且把数据保存到csv文件当中。
import requests
from lxml import etree
import csv
doubanUrl = 'https://movie.douban.com/top250?start={}&filter='
# 第一步获取网页源码
def getSource(url):
    # 反爬 填写headers请求头
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'
    }
     response = requests.get(url,headers=headers)
    # 防止出现乱码
    response.encoding = 'utf-8'
    # print(response.text)
    return response.text
    # 第二步定义一个函数 获取电影信息
def getEveryItem(source):
 html_element = etree.HTML(source)
 movieItemList = html_element.xpath('//div[@class="info"]')
  # 定义一个空的列表
    movieList = []
     for eachMoive in movieItemList:
 # 创建一个字典 像列表中存储数据[{电影一},{电影二}......]
        movieDict = {}
         title = eachMoive.xpath('div[@class="hd"]/a/span[@class="title"]/text()') # 标题
        otherTitle = eachMoive.xpath('div[@class="hd"]/a/span[@class="other"]/text()')  # 副标题
        link = eachMoive.xpath('div[@class="hd"]/a/@href')[0]  # url
        star = eachMoive.xpath('div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()')[0] # 评分
        quote = eachMoive.xpath('div[@class="bd"]/p[@class="quote"]/span/text()')  # 引言(名句)
 if quote:
            quote = quote[0]
        else:
            quote = ''
        # 保存数据
        movieDict['title'] = ''.join(title+otherTitle)
        movieDict['url'] = link
        movieDict['star'] = star
        movieDict['quote'] = quote
        movieList.append(movieDict)
        print(movieList)
    return movieList
    # 保存数据
def writeData(movieList):
with open('douban.csv','w',encoding='utf-8',newline='') as f:
  writer = csv.DictWriter(f,fieldnames=['title','star','quote','url'])
  writer.writeheader() # 写入表头
   for each in movieList:
        writer.writerow(each)
 if __name__ == '__main__':
    movieList = []
      # 一共有10页
    for i in range(10):
    pageLink = doubanUrl.format(i * 25)
   source = getSource(pageLink)
   movieList += getEveryItem(source)
 writeData(movieList)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值