2021/4/30爬虫第八次课(xpath语法、lxml模块)

文章目录

  • 一、xpath简介
    • 1.1概念
    • 1.2chrome插件--XPath Helper使用
    • 1.3xpath的快速入门
  • 二、lxml模块的使用
  • 三、案例
    • 附代码

一、xpath简介

1.1概念

XPath 是一门在 XML 文档中查找信息的语言。XPath 用于在 XML 文档中通过元素和属性进行导航。
xpath就是一种可以根据地址找人的技术 确定的路径
xpath(XML Path Language) 可以在树状结构中寻找结点 可以通过元素和属性进行导航
解决一些 网页结构明显的 数据解析
补充:
html 超文本标记语言
xml 可扩展标记语言
lxml 是一个Python第三方的库 它可以把这个html文本转换成xml对象(element对象) 使用xpath语法进行导航了
元素节点,表示的是html中的标签

1.2chrome插件–XPath Helper使用

https://huajiakeji.com/web-development/2018-01/892.html

1.3xpath的快速入门

2021/4/30爬虫第八次课(xpath语法、lxml模块)_第1张图片
查找某个特定的节点或者包含某个指定的值的节点
2021/4/30爬虫第八次课(xpath语法、lxml模块)_第2张图片

二、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)

三、案例

豆瓣top250电影
需求: 爬取 电影的名字 评分 引言 详情页的url 1-10页 保存到csv文件当中
​
思路分析
1 明确url (是否是静态网页,对比源代码与检查)
2 先像目标url发起请求 获取网页源码
3 可以把网页源码通过 etree.HTML 生成一个element对象
element对象 通过xpath进行导航   电影的名字 评分 引言 详情页的url
4 我们可以把数据先保存到一个字典里面 {
     title:'肖申克的救赎','start':9.7...} ,{
     title:'霸王别姬','start':9.7...} 在把这些字典保存到一个列表当中
5 把列表中的数据存到csv文件当中
​
细节逻辑:
1 doubanUrl 做了一个格式化的字符串 
# 当要占位的内容是一个变量的时候 用 f'{变量名}'的方式
# s1 = '蜘蛛侠'
# s2 = '蝙蝠侠'
# r = f'hello {s1},{s2}'
# print(r)
a = 'python'
s = f'i like {a}'
# r = s.format('python')
print(s)# /d /s /f 占位
​
​
2 xpath 语句的应用
本着一个先抓大 再抓小的原则
 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()')3 非空判断
我们发现有的电影 是没有引言
b = []
 b[0]
IndexError: list index out of rangeif quote:
            quote = quote[0]
        else:
            quote = ''
​
​
4 保存数据 如果是csv的格式
先把数据放到字典里面 然后在把数据放到列表里面
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)5 翻页的处理
​
通过格式化的字符串进行动态的替换 
经过分析 有10for i in range(10):
    pageLink = doubanUrl.format(i * 25)
 
6 数据存储的问题
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)
​
经过 总结这个案例当中 50用到的都是基础班的知识 join() 非空判断 字符串的格式 数据的增加的处理 range()函数
爬虫的技术 xpath

附代码

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


# 保存数据 次数 Ip检测  代理Ip(付费)
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)

补充
response.content bytes类型 内容是二进制字节流 通常用来保存图片等二进制文件
response.text str类型 unicode编码
无论pycharm用的是虚拟环境还是全局,安装模块时在pycharm Terminal中pip install …

你可能感兴趣的:(爬虫,xpath,html)