【foooooot】六只脚数据列表页采集案例


和青山 奏江河
我知青山江河乐
抚琴为人 无人知我乐
“洋洋兮又复巍峨”
来客忽笑我
声声所念 来人皆可得
徒余留 明月忆往昔
温酒会知音
借问人间 知我者能有几
三尺瑶琴碎骨兮
似绝弦断悲心
孑然一身 苍茫天地兮
                     🎵 国风堂、哦漏《知我》


使用 Requests 与 lxml 实现 Foooooot 旅游列表爬取

本文演示如何用 requests + lxmlfoooooot.com 抓取旅行线路列表,涵盖请求封装、页面解析、数据抽取等步骤。

一、项目背景

Foooooot 是一个分享各地旅行、徒步、自驾等线路的网站。在无法使用 Scrapy 时,我们也可以借助轻量级的 requests + lxml 组合,实现同样的列表页爬取功能。

二、环境准备
  • Python 3.7+
  • 安装依赖:
    pip install requests lxml
    
    
三、核心代码
# -*- coding:utf-8 -*-
import re
import requests
from lxml import etree

# 全局 headers 和 cookies
HEADERS = {
    'User-Agent': (
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) '
        'AppleWebKit/537.36 (KHTML, like Gecko) '
        'Chrome/126.0.0.0 Safari/537.36'
    ),
}
COOKIES = {
    "csrftoken": "cookie 信息",
    "sessionid": "cookie 信息"
}

def fetch(url: str) -> etree._Element:
    """
    用 requests 获取页面并返回解析后的 etree 对象
    """
    resp = requests.get(url, headers=HEADERS, cookies=COOKIES, timeout=10)
    resp.raise_for_status()
    return etree.HTML(resp.text)

def parse_list(tree: etree._Element) -> list:
    """
    解析列表页节点,返回一个包含所有线路信息的 dict 列表
    """
    items = []
    nodes = tree.xpath("//div[@class='listSection']/ul[@class='tripsList']/li")[1:-1]
    for node in nodes:
     	title = "".join(node.xpath(".//p[@class='trip-title']/a//text()")).strip()
        url = node.xpath(".//p[@class='trip-title']/a/@href")[0]
        unstr = "".join(node.xpath(".//td[1]/div/dl/dd//text()")).strip()
        code = url.split("/")[-2]
        date_str = re.findall(r"\d{4}-\d+-\d+", unstr)[0]
        addr = "".join(node.xpath(".//tr[1]/td[1]/div/dl/dd[3]//text()")).split(":")
        address_src, address_des = addr[0].strip(), addr[-1].strip()


        items.append({
            "title": title,
            "url": url,
            "dateStr": date_str,
            "code": code,
            "addressSrc": address_src,
            "addressDes": address_des,
            "flag": 0,
        })
    return items

def main():
    # 单页测试 URL(以“天安门”为关键词)
    url = (
        "http://www.foooooot.com/search/trip/all/432/"
        "all/weight/descent/?keyword=%E5%A4%A9%E5%AE%89%E9%97%A8"
    )
    tree = fetch(url)
    for item in parse_list(tree):
        print(item)

if __name__ == '__main__':
    main()
四、代码解析
  1. 请求封装(fetch)
    • 使用 requests.get 发起 HTTP GET 请求,带上自定义 HEADERS 和 COOKIES,模拟浏览器行为。
    • resp.raise_for_status() 确保非 200 响应会抛出异常。
  2. HTML 解析 (lxml.etree)
    • etree.HTML(resp.text) 将响应内容解析为可执行 XPath 操作的树形结构。
  3. 列表数据抽取 (parse_list)
    • //div[@class=‘listSection’]/ul/li 定位所有条目节点,跳过第一和最后一个非数据节点。
    • 利用 .xpath() 提取标题、链接、日期等字段,并通过正则 \d{4}-\d±\d+ 拆出日期。
    • 经过清洗后,将每条记录组装成 dict,方便后续处理或入库。
  4. 运行流程 (main)
    • 构造测试 URL,调用 fetch 和 parse_list,最后打印所有抓取到的条目。
五、扩展与优化
  • 多页循环:将主流程改为 while next_page_url,实现自动翻页。
  • 动态代理:在 requests.get 中加入 proxies 参数,避免 IP 限制。
  • 结果存储:可将 items 写入文件、数据库或消息队列。
  • 异常处理:在网络不稳定或解析失败时,加重试机制与日志。
总结

通过 requests + lxml,我们可以快速搭建一个轻量化的爬虫脚本,适用于简单列表页的抓取需求。核心思路包括请求封装、XPath 抽取、正则清洗以及循环控制。后续如需更完善的管道、调度与去重,可考虑使用 Scrapy 或其他爬虫框架,但数据解析部分的思路基本一致。