爬虫笔记12:lxml模块和xpath语法、join()方法

一、基本概念
不同的网页结构,我们灵活的采用不同的技术。
• XPath(XML Path Language)是一种XML的查询语言,他能在XML树状结构中寻找节点。XPath 用于在 XML 文档中通过元素和属性进行导航
• xml是一种标记语法的文本格式,xpath可以方便的定位xml中的元素和其中的属性值。
html 超文本标记语言;xml 可扩展标记语言;lxml 是一个Python第三方的库 它可以把这个html文本转换成xml对象(element对象) 使用xpath语法进行导航了。

结点的关系:

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

在这里插入图片描述
父(Parent) :book元素是title、author、year、price元素的父
子(Children) :title、author、year、price都是book元素的子

二、xpath基本用法
1、启用快捷键 ctrl + shift + x

2、基本语法
在这里插入图片描述
比如,我们要爬取下图中红框处的‘python开发工程师’,第一步是点击绿框中的小箭头,之后鼠标移到红框处,控制台就选定到黄框,也就是一个div标签中的classs属性值为iteminfo__line1__jobname的
在这里插入图片描述
由此,我们xpath可以写成:
//div[@class=“iteminfo__line1__jobname”]/span/@title

具体说明:
// 不要考虑位置
[] 谓语 用来查找某个特定的节点或者包含某个指定的值的节点 谓语被镶嵌在方括号当中
@ class=“iteminfo__line1__jobname” 选取某个属性
/ 去找这个 class=“iteminfo__line1__jobname” div标签下面的 span标签
@title 选取title属性

三、lxml模块的使用
1、安装 pip install lxml -i https://pypi.douban.com/simple
2 、功能 html 转换成element对象 有了element对象之后就可以使用xpath语法进行导航了

3 、使用
3.1 from lxml import etree
3.2 得到目标网页的源代码文件(html)
3.3 etree.HTML(网页源码) --> element对象
3.4 element.xpath(xxxx)

from lxml import etree
import csv


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)
# 获取li标签下面的href属性
links = html_element.xpath('//li/a/@href')
# print(links)
# 获取li标签下面a标签的文本内容
result = html_element.xpath('//li/a/text()')
# print(result)

# 需求是把二者的结果保存到一个字典当中然后存储的csv文件当中
# 例如 {'href':'link1.html','title':'first item'}, {'href':'link2.html','title':'second item'}...

titles = ('href','title')
lst = []
for link in links:
    d = {}
    d['href'] = link
    # print(links.index(link))
    d['title'] = result[links.index(link)]
    # print(d)
    lst.append(d)

with open('练习.csv','w',encoding='utf-8',newline='') as file_obj:
    writer = csv.DictWriter(file_obj,titles)
    writer.writeheader()
    writer.writerows(lst)

结果:

四、豆瓣top250电影
需求: 爬取豆瓣top250电影详情页 (1-10页)的url、电影的名字、评分 、引言 ,并 保存到csv文件当中。

import requests
from lxml import etree
import csv

# 目标Url
doubanUrl = 'https://movie.douban.com/top250?start={}&filter='

# 定义一个函数 获取网页源码
def getSource(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36'
    }
    response = requests.get(url,headers=headers)
    response.encoding = 'utf-8'
    return response.text

# 解析数据 电影的名字 评分 引言 详情页的url
def getEveryItem(source):
    html_element = etree.HTML(source)
    # class="info" 电影的名字 评分 引言 详情页的url 25
    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
        print(movieDict)
        movieList.append(movieDict)

    return movieList


# 保存数据 
def writeData(movieList):

    with open('douban.csv','w',encoding='utf-8',newline='') as file_obj:
        writer = csv.DictWriter(file_obj,fieldnames=['title','star','quote','url'])
        writer.writeheader()
        for each in movieList:
            writer.writerow(each)


if __name__ == '__main__':
    movieList = [] 

    for i in range(10):
        pageLink = doubanUrl.format(i * 25)

        source = getSource(pageLink)

        movieList = getEveryItem(source) # 保存的最后一页 movieList = movieList + getEveryItem(source)  a = 1  a += 1

    writeData(movieList)

补充:
join() 方法:以指定的方式把字符串或列表连接成一个新的字符串,并返回。

a = ['1','2','3']
b = '-'.join(a)
print(b) # 1-2-3

c = 'hello'
d = '*'.join(c)
print(d) # h*e*l*l*o

在爬虫笔记25中有具体应用案例。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值