Python中如何利用机器学习生成XPath实现通用爬虫?
做通用爬虫,现在的正文提取已经很稳了 95%以上的正文提取率可以实现. (通用提取和 xpaht,css 等选择器)
但是为了更精确,对某域名或类型网站下,进行随机抽取 10-20 个网页。
用上述正文抽取的 content, 和原网页 html.
进行学习,然后推测出 xpath 之类。生成 xpath 配置项.
目标:以 95%的成功率实现 99.99%的成功率.
老哥们有好的思路么?[@binux](/user/binux)
参考:
Python中如何利用机器学习生成XPath实现通用爬虫?
机器学习个蛋啊,选择器总共能用的特征就 class,ID,属性那么几个,多个页面比对,组合一下选个最好的就完了
这个想法挺有意思的,但“通用爬虫”和“机器学习生成XPath”这两个概念放在一起,我得给你泼点冷水。目前没有能直接“一键生成”所有网站XPath的通用机器学习模型。不过,我们可以换个思路,用一些智能化的方法来辅助定位和提取数据,这比纯手写XPath要高效和健壮得多。
核心思路不是让AI去“写”XPath,而是让它去“识别”网页中我们想要的内容(比如商品标题、价格),然后我们再用程序去生成相对稳健的定位路径。下面是一个结合 scrapy 和 parsel 的实用示例,它模拟了“智能定位”的过程:
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}'
为什么不用纯机器学习模型?
- 网页结构千差万别:每个网站的HTML结构、类名、标签都完全不同,没有足够大且标注好的通用训练数据集。
- XPath本身是规则语言:它的生成更适合用基于规则的程序(就像上面的策略组合),而不是概率模型。
- 维护成本高:一个训练出的模型一旦网站改版,可能需要重新标注数据、重新训练,而规则组合调整起来更快。
更现实的“智能化”方案是:
- 使用现成的提取库:比如
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 网站的爬虫, 感觉维护特别费劲
求此工具入口

