7.23之爬虫开发中的 Requests 高级用法与 XPath 解析技术

首先简介:

人话来说就是通过Xpath代码爬取网页里面我们想要的信息,比如小编这里就是爬取了星座运势,星座日期,星座运势;大家可以用来提取网页数据,比如球队信息,高考录取全部信息等等,这里不介绍,下面上干货

上干货之前

对于一些网站,大规模爬取或大规模频繁请求时,网站可能会出现以下情况: 弹出验证码; 跳到登录认证页面; 直接封禁客户端的IP,一段时间内无法访问;

或者直接换网就行

通过代理设置可以解决上述问题,代理服务器(Proxy Server)的功能是代理网络用户去取得网络信息。形象地说,它是网络信息的中转站,是个人网络和Internet服务商之间的中间代理机构,负责转发合法的网络信息,对转发进行控制和登记。

大头之Requests 库:爬虫开发的利器

Requests 库作为 Python 中处理 HTTP 请求的优秀第三方库,不仅能实现基本的网络请求,其高级功能更能应对复杂的爬虫场景,提升爬取效率与稳定性。

会话简介

在 Web 开发中,会话(Session)是维护用户状态的关键机制。服务器通过会话对象存储用户数据,以便在用户后续操作中提供个性化服务。Requests 库的 session 对象完美模拟了这一过程,能自动处理 Cookies,轻松实现会话保持。

其核心优势在于:一次登录后,后续请求无需重复提交身份信息,只需通过 session 对象发起请求即可携带必要的 Cookies 信息。例如,在登录 QQ 邮箱时,通过 session.post () 方法提交账号密码后,后续的邮件访问请求可直接使用该 session 对象,无需再次验证,极大简化了需要身份认证的爬虫开发。

session 对象提供了丰富的方法,包括 get ()、post () 用于发起请求,cookies () 获取 Cookies 信息,headers () 查看请求头等,满足会话管理的各种需求。

对战代码

XPath:精准解析网页数据

获取网页内容后,高效解析数据是爬虫开发的另一关键环节。XPath 作为一门在 XML/HTML 文档中查找信息的语言,凭借其强大的路径表达式,成为数据解析的首选工具。

XPath 基本语法与规则

XPath 通过路径表达式选取文档中的节点,常用规则包括:

  • 斜杠(/)表示从根节点选取,双斜杠(//)表示从任意位置选取节点;
  • 点(.)代表当前节点,双点(..)代表父节点;
  • @符号用于选取属性,如 //@href 可获取所有 href 属性值。

谓语(Predicates)用于筛选特定节点,如 /bookstore/book [1] 选取第一个 book 节点,//title [@lang='eng'] 选取 lang 属性为 eng 的 title 节点。通配符(、@、node ())可匹配未知元素,“|” 运算符则支持同时选取多个路径,极大增强了节点选取的灵活性。

lxml 库:XPath 解析的强力支撑

Python 的 lxml 库提供了 etree 模块,专为 XML/HTML 解析设计,与 XPath 配合使用能高效提取数据。etree.HTML () 方法可将 HTML 字符串转换为可解析的 Element 对象,并自动补全不完整的标签,确保解析准确性;parse () 方法用于解析本地文件;tostring () 方法则能将 Element 对象转回字符串形式。

在实际应用中,通过 XPath 表达式与 etree 方法结合,可轻松完成各种解析任务:

  • 选取子节点或子孙节点://li/a
  • 获取父节点属性://a [@href="link4.html"]/../@class
  • 过滤特定属性的节点://li [@class="item-1"]
  • 提取文本内容://li [@class="item-1"]/a/text ()
  • 获取属性值://li/a/@href
    import requests
    from lxml import etree
    import csv
    
    
    def get_html(url, timeout=30):
        """获取网页内容"""
        try:
            headers = {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36"
            }
            r = requests.get(url, timeout=timeout, headers=headers)
            r.raise_for_status()  # 检查请求是否成功
            r.encoding = "utf-8"  # 手动指定编码
            return r.text
        except Exception as error:
            print(f"网页内容获取失败: {error}")
            return None
    
    
    def parse(html):
        """解析网页,提取星座名称、日期和运势概述"""
        if not html:
            return []
    
        doc = etree.HTML(html)
        out_list = []
        # 1. 修正XPath错误:移除末尾多余的"]",并准确定位星座容器
        constellations = doc.xpath('//*[@id="list"]/div[1]/div/dl/dd')  # 去掉末尾多余的"]"
    
        for item in constellations:
            try:
                # 2. 提取文本必须用text(),否则获取的是元素对象(导致strip()错误)
                # 使用相对路径"./"从当前item节点开始查找,避免全局重复提取
                name = item.xpath('./strong/text()')[0].strip()  # 星座名
                date = item.xpath('./small/text()')[0].strip()   # 对应日期
                overview = item.xpath('./p/text()')[0].strip()   # 运势概述
    
                out_list.append([name, date, overview])
                print(f"已提取: {name} ({date})")
            except IndexError:
                print("部分信息缺失,跳过该星座")
                continue
            except Exception as e:
                print(f"解析出错: {e}")
                continue
    
        return out_list
    
    
    def save_csv(items, path):
        """保存数据到CSV文件"""
        if not items:
            print("没有数据可保存")
            return
    
        # 3. 修正文件格式:将.text改为.csv(符合CSV格式)
        with open(path, 'w', newline='', encoding='utf-8-sig') as f:
            csv_writer = csv.writer(f)
            csv_writer.writerow(['星座名字', '对应日期', '运势概述'])  # 表头
            csv_writer.writerows(items)  # 写入数据
        print(f"数据已保存到 {path}")
    
    
    if __name__ == "__main__":
        url = "https://www.xzw.com/fortune/"
        html = get_html(url)
        if html:
            constellation_list = parse(html)
            # 4. 修正文件后缀为.csv
            save_csv(constellation_list, '星座信息.csv')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值