Python中如何利用机器学习生成XPath实现通用爬虫?

做通用爬虫,现在的正文提取已经很稳了 95%以上的正文提取率可以实现. (通用提取和 xpaht,css 等选择器)

但是为了更精确,对某域名或类型网站下,进行随机抽取 10-20 个网页。

用上述正文抽取的 content, 和原网页 html.

进行学习,然后推测出 xpath 之类。生成 xpath 配置项.

目标:以 95%的成功率实现 99.99%的成功率.

老哥们有好的思路么?[@binux](/user/binux)

参考:


Python中如何利用机器学习生成XPath实现通用爬虫?

15 回复

机器学习个蛋啊,选择器总共能用的特征就 class,ID,属性那么几个,多个页面比对,组合一下选个最好的就完了


这个想法挺有意思的,但“通用爬虫”和“机器学习生成XPath”这两个概念放在一起,我得给你泼点冷水。目前没有能直接“一键生成”所有网站XPath的通用机器学习模型。不过,我们可以换个思路,用一些智能化的方法来辅助定位和提取数据,这比纯手写XPath要高效和健壮得多。

核心思路不是让AI去“写”XPath,而是让它去“识别”网页中我们想要的内容(比如商品标题、价格),然后我们再用程序去生成相对稳健的定位路径。下面是一个结合 scrapyparsel 的实用示例,它模拟了“智能定位”的过程:

import scrapy
from parsel import Selector
from w3lib.html import remove_tags

class SmartSpider(scrapy.Spider):
    name = 'smart_spider'
    
    def start_requests(self):
        # 假设我们要抓取一个电商页面
        url = 'https://example.com/product-page'
        yield scrapy.Request(url, callback=self.parse_product)

    def parse_product(self, response):
        """
        核心解析函数:综合多种策略定位元素,而非依赖单一固定XPath。
        """
        sel = Selector(response)
        
        # 策略1:优先使用包含特定class或id的精确选择器
        title = sel.xpath('//h1[@class="product-title"]/text()').get()
        price = sel.xpath('//span[contains(@class, "price")]/text()').get()
        
        # 策略2:如果精确选择器失效,尝试更通用的语义化选择
        if not title:
            # 尝试获取第一个h1标签,或者包含“产品”、“商品”等关键词的文本
            title_candidates = sel.xpath('//h1//text()').getall()
            title = title_candidates[0] if title_candidates else None
        
        if not price:
            # 尝试寻找包含货币符号或数字格式的文本
            price_candidates = sel.xpath('//*[contains(text(), "$") or contains(text(), "¥")]/text()').getall()
            price = price_candidates[0] if price_candidates else None
        
        # 策略3:作为保底,使用CSS选择器或更宽泛的XPath
        if not title:
            title = sel.css('title::text').get()
        
        # 清理数据
        if title:
            title = title.strip()
        if price:
            price = price.strip().replace('$', '').replace('¥', '')

        yield {
            'title': title,
            'price': price,
            'url': response.url
        }

# 辅助函数:生成相对XPath(示例,实际更复杂)
def generate_robust_xpath(selector, element):
    """
    这是一个简化的概念性函数。实际应用中,你需要分析element的id、class、位置等属性,
    生成一个不依赖绝对路径,而是基于相对位置或稳定属性的XPath。
    例如:'//div[@id="main"]//p[contains(@class, "content")]'
    """
    # 这里只是一个示意,真实逻辑需要解析DOM树
    tag = element.root.tag
    class_attr = element.attrib.get('class', '')
    if class_attr:
        return f'//{tag}[contains(@class, "{class_attr.split()[0]}")]'
    else:
        # 退回到基于父节点的相对定位
        return f'//{tag}'

为什么不用纯机器学习模型?

  1. 网页结构千差万别:每个网站的HTML结构、类名、标签都完全不同,没有足够大且标注好的通用训练数据集。
  2. XPath本身是规则语言:它的生成更适合用基于规则的程序(就像上面的策略组合),而不是概率模型。
  3. 维护成本高:一个训练出的模型一旦网站改版,可能需要重新标注数据、重新训练,而规则组合调整起来更快。

更现实的“智能化”方案是:

  • 使用现成的提取库:比如 extruct(提取微数据)、goose3(提取文章正文),它们内置了启发式规则。
  • 视觉分析:结合Selenium等工具,通过元素在浏览器中的实际位置、大小来定位,这比分析原始HTML更接近人类视觉。
  • 差分分析:对多个相似页面(如商品列表)进行对比,自动找出重复模式对应的数据区域。

总结:别指望有全自动的XPath生成模型,用规则组合加智能回退策略更靠谱。

哈哈哈,正解

这年头怎么什么都机器学习啊。

别喷机器学习啊,都是工具,有用就行,多搞点数据即使直接丢特征进 svm 也比手动写规则省事,精确。
除了一楼提到的几个特征,渲染后对应的位置、面积、长宽比,还有单词 /字符数之类的,应该也是很好的辅助。

据我观察,大部分新闻网站,一个标签下有大段文字,或者有很多样式一致(指字体)的标签包裹小段文字

html 头部尾部清洗+文本密度
以前我们公司是这么做的

xpath 处理 js 还是很麻烦

前公司做过用文本密度,准确率 95 以上。gayhub 上有个 node 的实现,准确率很高,但是性能稍微差点,要用 JSdom 渲染一遍。

目前我用过最好的是印象笔记的 Chrome 剪藏插件。。。

话说很多网站根本不靠谱的。class id 属性不太好使(参见极端例子: https://www.kawabangga.com/posts/2240 )文本密度好一些

目前我的比印象笔记的 Chrome 剪藏插件识别率更好。因为我是组合通用抓取和 xpath 规则等。

现在是可以根据文本内容自动推算出正文区域,设置 xpath 是更精确一点,不设置也行。(正常提取和 headless 等)

也设计了可视化的 xpath 提取工具,然后写入配置项,一个站 20s 左右。

现在就想人工介入的更少。

不同网站的 class id 属性不一样

楼主有没有写过 React 网站的爬虫, 感觉维护特别费劲

求此工具入口

回到顶部