五、XPath实战:快速定位网页元素

🍀分析网站

本节我们来爬取豆瓣电影,在实战开始前,我们需要搞懂爬取的流程,在清楚爬取的步骤后,我们方可事半功倍

  • 导入需要的库
  • 分析获取网站URL
  • 获取HTML页面
  • etree解析
  • 使用Xpath插件进行测试标签
  • 编写Xpath语法,并存储数据

🍀获取每页URL

首页需要导入我们需要的库

import requests
from lxml import etree

接下来需要获取前5页的URL,下面我们可以一起来看看它们之间的规律

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

不难看出规律为0,20,40,60,80,那么我们获取这几页URL就好办了

urls = []
for i in range(0,5,1):
    i*=20
    url = 'https://movie.douban.com/review/best/?start={}'.format(i)
    urls.append(url)

🍀获取每页URL中的影评URL

接下来我们需要获取每页中影评的具体URL

右击鼠标点击检查,我们就会看到具体的URL,为了测试Xpath语法,我们需要打开Xpath插件(本文结尾我会奉上下载链接)

在这里插入图片描述
不难分析此URL可以从,总的h2标签下的,a标签中的,href属性下手
在这里插入图片描述

detail_urls = []
for d_url in urls:
    reponse = requests.get(d_url, headers=_headers)
    # 编码转码
    content = reponse.content.decode('utf8')
    # 解析html字符串
    html = etree.HTML(content)
    # 利用Xpath提取每个电影影评的url
    detail_url = html.xpath('//h2/a/@href')
    detail_urls.append(detail_url)

🍀获取电影影评数据

做完先前的工作,这里可以说是核心的步骤了,获取真正有用的数据

获取电影名

title = html.xpath('//div[@class="subject-title"]/a/text()')[0][2:]

这里会有人好奇为什么后面需要切一下,原因如下,前面有一些无用的数据,需要清除
在这里插入图片描述

获取评论者和评分

commenter = html.xpath('//header/a/span/text()')[0]
rank = html.xpath('//header//span/@title')[0]
     if len(rank) == 0:
          _rank = weidafen
     else:
          _rank = rank

获取影评

comment = html.xpath('//div[@id="link-report"]//p/text()')
            comment = ''.join(comment) # 拼接

因为影评不是连续的,所有需要用.join()进行拼接一下

获取评价时间

 time = html.xpath('//header/span[3]/text()')[0]

🍀修饰+完整代码

从前辈那里学到了一个技巧,使用异常处理模块,完整代码如下

import requests
from lxml import etree

# 获取5页的url
urls = []
for i in range(0,5,1):
    i*=20
    url = 'https://movie.douban.com/review/best/?start={}'.format(i)
    urls.append(url)

# 获取每一页url中,每个影评的具体url
_headers = {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
            }
detail_urls = []
for d_url in urls:
    reponse = requests.get(d_url, headers=_headers)
    # 编码转码
    content = reponse.content.decode('utf8')
    # 解析html字符串
    html = etree.HTML(content)
    # 利用Xpath提取每个电影影评的url
    detail_url = html.xpath('//h2/a/@href')
    detail_urls.append(detail_url)


# 获取电影影评的数据
moives=[]
weidafen = "未打分"
i = 0
for page in detail_urls:
    for url in page:
        try:
            response = requests.get(url, headers=_headers)
            content = response.content.decode('utf8')
            html = etree.HTML(content)
            # 抓取电影名
            title = html.xpath('//div[@class="subject-title"]/a/text()')[0][2:]
            # 抓取评论者和评分
            commenter = html.xpath('//header/a/span/text()')[0]
            rank = html.xpath('//header//span/@title')[0]
            if len(rank) == 0:
                _rank = weidafen
            else:
                _rank = rank
            # 抓影评
            comment = html.xpath('//div[@id="link-report"]//p/text()')
            comment = ''.join(comment) # 拼接
            # 抓评价时间
            time = html.xpath('//header/span[3]/text()')[0]
            movie = {
                "title": title,
                "commenter": commenter,
                "rank": _rank,
                "comment": comment,
                "time": time
            }
            moives.append(movie)
        except:
            continue
    i+=1
    print("-------第{}页已爬取-------".format(i))
print(moives)

🍀保存数据到csv

保存后的数据有一点问题,愿大佬指正

import requests
from lxml import etree
import csv
# 获取5页的url
urls = []
for i in range(0,5,1):
    i*=20
    url = 'https://movie.douban.com/review/best/?start={}'.format(i)
    urls.append(url)

# 获取每一页url中,每个影评的具体url
_headers = {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
            }
detail_urls = []
for d_url in urls:
    reponse = requests.get(d_url, headers=_headers)
    # 编码转码
    content = reponse.content.decode('utf8')
    # 解析html字符串
    html = etree.HTML(content)
    # 利用Xpath提取每个电影影评的url
    detail_url = html.xpath('//h2/a/@href')
    detail_urls.append(detail_url)

fp = open('data.csv', 'w', newline="", encoding="utf-8-sig")
writer = csv.writer(fp)
writer.writerow(('电影名','评分者', '评分', '评论', '时间'))
# 获取电影影评的数据
moives=[]
weidafen = "未打分"
i = 0
for page in detail_urls:
    for url in page:
        try:
            response = requests.get(url, headers=_headers)
            content = response.content.decode('utf8')
            html = etree.HTML(content)
            # 抓取电影名
            title = html.xpath('//div[@class="subject-title"]/a/text()')[0][2:]
            # 抓取评论者和评分
            commenter = html.xpath('//header/a/span/text()')[0]
            rank = html.xpath('//header//span/@title')[0]
            if len(rank) == 0:
                _rank = weidafen
            else:
                _rank = rank
            # 抓影评
            comment = html.xpath('//div[@id="link-report"]//p/text()')
            comment = ''.join(comment) # 拼接
            # 抓评价时间
            time = html.xpath('//header/span[3]/text()')[0]
            # movie = {
            #     "title": title,
            #     "commenter": commenter,
            #     "rank": _rank,
            #     "comment": comment,
            #     "time": time
            # }
            moives.append([title,commenter,rank,comment,time])
        except:
            continue
    i+=1
    print("-------第{}页已爬取-------".format(i))
    # 写入数据
    for rows in moives:
        writer.writerow(rows)
fp.close()

注意:Xpath提取数据返回结果是列表,后续操作需要使用列表操作

🍀总结

Xpath的主要流程可以用下图表示
在这里插入图片描述

🍀Xpath插件

链接:https://pan.baidu.com/s/1Pn3dmJgJADIUKcjsDs8cJw?pwd=zsjw
提取码:zsjw
–来自百度网盘超级会员V5的分享

请添加图片描述

挑战与创造都是很痛苦的,但是很充实。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小馒头学python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值