网络爬虫(第二部)

上次我们主要介绍了requests库基于正则表达式的方法实现爬虫,简单提了xpath的方法。

今天我们正式学习导入lxml库使用xpath的方法实现爬虫,介绍第二个爬虫库selenium。

requests库用来向网页发送请求,返回一个包含html文件、content等内容的对象,实现根据网页内容结构特点设计代码爬取网页内容,但是它无法驱动浏览器的行为,比如鼠标单击翻页等,selenium就是用来驱动浏览器行为。

lxml库xpath语法实现爬虫

在上一篇网页爬虫的博客中,我们通过分析 requests 库返回内容的结构特点,设计正则表达式来提取目标数据。这种方法需要精准观察目标内容的上下文特征来编写匹配规则,但正则表达式对 HTML 结构的容错性差,一旦网页标签嵌套、属性格式稍有变化,正则就可能失效。

而 HTML 本身是遵循固定语法的结构化文档,标签嵌套、属性定义都有明确规范 ------ 针对这种 "整齐" 的网页结构,有没有更规范、更易维护的爬取方法?答案是肯定的,lxml 库 就是处理这类场景的绝佳选择。

lxml库

lxml 是基于 C 语言库 libxml2 封装的高性能 XML/HTML 解析库。具有如下优势:

  1. 结构化解析:直接识别 HTML 标签的层级、属性、文本等语义,无需关注 "字符层面" 的匹配;
  2. 支持 XPath/CSS 选择器:两种简洁的语法定位目标元素,比正则更贴合 HTML 结构;
  3. 容错性强:能自动修复不规范的 HTML 代码(如未闭合的标签),适配实际场景中 "不完美" 的网页;
  4. 性能优异:底层基于 C 实现,解析速度远快于纯 Python 实现的解析方式。
xpath语法
注意事项
案例

目标:爬取虎扑热榜信息,网站https://m.hupu.com/hot

网页:

思路:通过//div[@class="hot_hot-page-item-title__HL2kw"]找到所有热榜信息所在的div容器,xpath()方法返回成列表结构,循环结构输出。

代码:

python 复制代码
'''爬取虎扑热榜(xpath)更简洁'''
import requests
from lxml import etree

r=requests.get("https://m.hupu.com/hot")
# HTML 提供解析在线html文件的方法
tree=etree.HTML(r.text)
topics=tree.xpath('//div[@class="hot_hot-page-item-title__HL2kw"]/text()')
#etree.xpath()方法会返回列表形式

for i,j in enumerate(topics):  
    print('热点第',i+1,'话题:',j)

enumerate() 是 Python 处理列表(或可迭代对象)的常用技巧,核心作用是同时获取列表元素的「索引」和「对应的值」

执行结果:

ua伪装

上一篇博客我们通过手动的方法找到网页的User-Agent进行ua伪装,今天通过相关fake_useragent

实现。

案例

目标:爬取网页图片24张。

网页:https://10wallpaper.com/List_wallpapers/page/1

思路:xpath()方法返回图片的url(网址),循环结构存储图片。导入第三方库fake_useragent实现ua伪装。

代码:

python 复制代码
import fake_useragent
import requests
from lxml import etree
import os  #操作文件夹存储图片

n=0
def count():
    global n
    n+=1
    return n

# 新建一个文件夹用于存储图片
if not os.path.exists("./Picture"):
    os.mkdir("./Picture")

head = {
"User-Agent": fake_useragent.UserAgent().random
} #定义头文件用于后面ua伪装

for i in range(1, 3): #爬取三十张图片分布在三张网页,循环结构来实现翻页
    url = f"https://10wallpaper.com/List_wallpapers/page/{i}"
    # 发送请求
    resp = requests.get(url, headers=head) #请求的头文件进行ua伪装
    # 响应回去的返回数据
    result = resp.text
    tree = etree.HTML(result) #etree库解析网页
    p_list = tree.xpath("//div[@id='pics-list']/p")
    for p in p_list:
        img_url = p.xpath("./a/img/@src")[0]
        img_url2='https://10wallpaper.com'+img_url
        print(img_url2)
        img_name = count()
        print(img_name)
        img_resp = requests.get(img_url2, headers=head)
        img_content = img_resp.content  #获取图片,网页的图片存在requests.get返回对象的content
        with open(f"./Picture/{img_name}.jpg", "wb") as fp:
            fp.write(img_resp.content)

执行:

案例2:爬取豆瓣电影信息,自行尝试

代码:

python 复制代码
'''爬取豆瓣电影信息'''
# pip install fake_useragent -i https://pypi.tuna.tsinghua.edu.cn/simple
# pip install lxml -i https://pypi.tuna.tsinghua.edu.cn/simple
import fake_useragent
import requests
from lxml import etree
import re

url = 'https://movie.douban.com/top250'
header={'User-Agent':fake_useragent.UserAgent().random}
resp = requests.get(url, headers=header)
# 新增:设置响应编码,避免中文乱码
resp.encoding = 'utf-8'
# 获取请求返回的数据
# print(resp.text)
result = resp.text
fp = open("doubanFilm.txt","w",encoding="utf8")
# 数据解析
# 错误1:注释掉了tree定义,导致tree变量未定义 → 取消注释
tree = etree.HTML(result)
li_list = tree.xpath("//ol[@class='grid_view']/li")
for li in li_list:
    try:
        film_name = li.xpath("./div/div[2]/div[1]/a/span[1]/text()")[0]
        film_actor = li.xpath("./div/div[2]/div[2]/p[1]/text()")
        # 错误2:pattern关键字参数后跟位置参数,违反语法规则 → 移除pattern=
        # 错误3:正则匹配容错性差,优化正则表达式
        actor_text = "".join([line.strip() for line in film_actor if line.strip()])
        dir_match = re.match(r"导演: (.+?) .+?主演: (.+)", actor_text)
        film_daoyan = dir_match.group(1) if dir_match else "未知导演"
        film_zhuyan = dir_match.group(2) if dir_match else "未知主演"

        # 错误4:用re.search替代re.match(match只匹配开头,search全局匹配),避免年份提取失败
        year_match = re.search(r"(\d{4})", actor_text)
        film_year = year_match.group(1) if year_match else "未知年份"

        # 错误5:提取引言时未做容错,无引言会报错 → 先判断列表是否为空
        film_quote_list = li.xpath("./div/div[2]/div[2]/p[2]/span/text()")
        film_quote = film_quote_list[0] if film_quote_list else "无引言"

        film_star = li.xpath("./div/div[2]/div[2]/div/span[2]/text()")[0]
        print(film_name, film_quote, film_star, film_daoyan, film_zhuyan, film_year)
        fp.write(film_name+'#'+film_quote+'#'+film_star+'#'+film_daoyan+'#'+film_zhuyan+'#'+film_year+'\n')
    except Exception as e:
        print(f"处理{film_name if 'film_name' in locals() else '未知电影'}时出错:{e}")
        pass
fp.close()

执行结果:

selenium库

selenium库介绍

1、 selenium是什么?

用于Web应用程序测试的工具。可以驱动浏览器执行特定操作,自动按照脚本

代码做出点击,输入,打开,验证等操作,就像真实用户所做的一样。

支持的浏览器包括IE,Firefox,Safari,edge,Chrome等。

2、 与requests库的区别?

selenium库是基于浏览器的驱动程序来驱动浏览器执行操作的,且浏览器可以实现网页源代码的渲染,

因此通过selenium库还可以轻松获取网页中渲染后的数据信息

3、selenium的工作原理

浏览器具有webdriver驱动,这个驱动是根据不同的浏览器开发的,

不同的浏览器使用不同的webdriver驱动程序且需要对应相应的浏览器版本,

webdriver驱动程序可以通过浏览器内核控制浏览执行指定命令

4、如何使用selenium?

使用前准备: a、安装selenium库 b、驱动浏览器的内核驱动

a、安装selenium,使用pip install selenium==4.11.0 -i https://pypi.mirrors.ustc.edu.cn/simple/

或在pycharm中安装

b、edge内核驱动地址 360浏览器使用的就是edge的内核,QQ浏览器使用IE,IE,

首先确定你的浏览器是使用哪个内核??

windows系统:下载下来的文件解压后放置在python安装地址的Scripts中

Linux和Mac系统:同上,注意:系统存在2个Python版本,确定当前运行的python

版本配置在环境变量中

edge驱动下载地址:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/?ch=1\&form=MA13LH

chrome驱动下载地址:https://chromedriver.storage.googleapis.com/index.html

firefox驱动下载地址:https://github.com/mozilla/geckodriver/releases

案例

打开一个网页:

python 复制代码
'''打开一个网页'''

from selenium import webdriver  #从selenium导入 webdriver(浏览器驱动)
from selenium.webdriver.edge.options import Options  #导入Edge浏览器的options类,这个类允许我们配置WebDriver的行为。

edge_options = Options()  ##创建一个0ptions类的实例,这将用于设置Edge浏览器的启动选项。
edge_options.binary_location = r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
driver =webdriver.Edge(options=edge_options)
driver.get('https://10wallpaper.com/List_wallpapers/page/1')
input('dengdai')

执行结果:

作业

大家可以基于前面的案例尝试完成作业代码

目标:使用selenium库实现网页翻页来爬取不同页面的图片

网页:www.gamewallpapers.com/index.php?start=0&page=

思路:xpath()方法输入图片所在位置//img[@class="zoom123" and @width="800",返回图片网址的列表,循环结构存入文件。

模拟浏览器单击实现翻页:

page2_btn = driver.find_element(By.XPATH, '//a//div[@id="page-number" and @class="zoom3" and text()="{j}"')

page2_btn.click()

代码:

python 复制代码
from lxml import etree  #导入lxml库用于解析网页,使用xpath
import os  #导入os库用于操作文件夹,存入图片
import requests  #导入requests库,使用content返回图片
from selenium.webdriver.common.by import By #导入by,在模拟单机行为时,选择路径语法
import time  #导入时间库


from selenium.webdriver.edge.options import Options #导入options类,用来配置浏览器启动行为
from selenium import webdriver  #导入webdriver模块,用来启动浏览器实现点击等操作
# 创建Edge浏览器配置对象
edge_options = Options()  
# 指定Edge浏览器程序的安装路径
edge_options.binary_location = r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
# 初始化Edge驱动并应用配置
driver = webdriver.Edge(options=edge_options)
# 访问游戏壁纸网站的分页页面
driver.get('https://www.gamewallpapers.com/index.php?start=0&page=')

# 新建一个文件夹用于存储图片
if not os.path.exists("./Picture2"):
    os.mkdir("./Picture2")



n=0

for j in range(2,4):
    #获取网页html,xpath找到图片地址返回一个列表
    result = driver.page_source
    tree = etree.HTML(result)
    img_src_list = tree.xpath('//img[@class="zoom123" and @width="800"]/@src') #这里使用两个@匹配图片结构img,因为我第一次只用了一个,结果还有另一类型图片也是class=zoom123,导致多下载了好多图片
    #循环结构存储图片
    for i in img_src_list:
        head = "https://www.gamewallpapers.com/"
        url = head + i
        n += 1
        print(n)
        print(url)  #打印下载的图片

        a = requests.get(url)
        b = a.content
        with open(f"./Picture3/{n}.jpg", "wb") as fp:
            fp.write(b)  #将图片导入文件夹

    page2_btn = driver.find_element(By.XPATH, '//a//div[@id="page-number" and @class="zoom3" and text()="{j}"')
    page2_btn.click()  #模拟浏览器单击实现翻页

执行结果:

相关推荐
电商API_180079052474 小时前
Python爬虫从入门到实战:核心技术与合规指南
大数据·数据库·爬虫
sugar椰子皮6 小时前
【爬虫框架-6】中间件的另一种写法实现
爬虫·中间件
三喵2237 小时前
跨域 iframe 内嵌的同源策略适配方案-Youtube举例
前端·爬虫
深蓝电商API7 小时前
Curl_cffi实战:完美伪装成真实浏览器TLS/JA3指纹
chrome·爬虫·反爬
啊巴矲7 小时前
小白从零开始勇闯人工智能:爬虫初级篇(2-网络爬虫(2))
爬虫
深蓝电商API9 小时前
爬虫数据增量更新:时间戳、offset、WebSocket 长连接方案
爬虫
陈老老老板9 小时前
让AI替你写爬虫:基于自然语言的 AI Scraper Studio 实战解析
人工智能·爬虫
sugar椰子皮9 小时前
【爬虫框架-5】实现一下之前的思路
开发语言·爬虫·python
oh,huoyuyan9 小时前
【实战案例】使用火语言RPA『表格数据提取』组件,批量爬取蔬菜价格+Excel 整理
爬虫·excel·rpa