摄影:产品经理餐前小菜
GNE 上线以后,很多同学在用户群里面问到,GNE 能否支持列表页自动提取?例如对于下图中的新闻标题列表:
能自动提取到如下图所示的数据:
[{'title': '上周汪文斌回应80多个提问 其中3件事尤其引人关注', 'url': 'https://news.163.com/20/0726/20/FIG6FJEG00019B3E.html'}, {'title': '成都美领馆关闭前24小时:现场有人高唱《大中国》', 'url': 'https://news.163.com/20/0726/19/FIG1NF9I00019B3E.html'}, {'title': '美驻成都总领馆现黑垃圾袋 外媒记者:似乎有碎纸片', 'url': 'https://news.163.com/20/0726/18/FIG0E0IQ0001899O.html'}, {'title': '美驻成都总领馆被通知关闭第3天:凌晨3点有车驶离', 'url': 'https://news.163.com/20/0726/16/FIFOFU580001899O.html'}, {'title': '新三板精选层下周一见', 'url': 'https://money.163.com/20/0726/07/FIEPSRPS00259DLP.html'}, {'title': '中巴驶入美驻成都领馆 安保开门时严加防范站成一排', 'url': 'https://news.163.com/20/0726/13/FIFDBAIV0001899O.html'}, {'title': '知情人:杀妻案嫌犯曾威胁前妻不同意离婚"命都没有"', 'url': 'https://news.163.com/20/0726/12/FIFC5VFG00019QIF.html'}]
想法非常好,但实现起来会面临一些问题。
不止一处列表
在一个页面,存在不止一处列表,如下图红色方框、蓝色方框和绿色方框,这三处,从 HTML 里面看,都是列表:
那么,程序怎么知道,应该提取哪个列表?如果把所有列表全部返回,那么用户怎么区分哪些是不需要的呢?如果传入一个 XPath 限定从特定的范围抓取列表,但是既然都传入 XPath 了,直接用这个 XPath 提取列表不就好了吗?
列表项里面哪个 URL 才是标题的 URL?
接下来,你能成功找到列表页所在的区域,那么如果每一行有多个链接,你如何知道哪一个<a>
标签中的文字是标题、哪一个@href
对应的网址是正文的网址?请看下图,如果不看文字内容,请问你能从 HTML 里面区分哪个红框中的网址对应的是正文网址吗?
所以GNE会怎么做?
GNE 从一开始就不相信各种各样的列表页能自动化完美提取,所以也不会去做完美自动化提取列表页的功能。GNE 要做的是,有限的自动化。
什么叫做有限自动化呢?如下图所示:
在调用list_extractor.extract
方法的时候,除了传入网页的 HtmlElement 外,还传入了一个feature
参数。这个参数的值是一个看起来像是直接从 Chrome 中复制的 XPath。
没错,feature 参数是你需要的目标列表里面任意一个标题的 XPath。你可以直接在 Chrome 中用开发者工具复制出来。
GNE 拿到 feature 参数以后,会自动从下往上检查它的祖先节点,寻找 feature 参数对应的标题所在的列表。
这样做的好处是显而易见的——第一,这个 XPath 本身已经限定了我需要的列表页所在的位置,所以即使当前页面有多个列表页也能正确识别;第二,feature 参数也能表示出我们需要提取的标题所在的具体标签。所以即使一个列表每一行有多个 <a>
标签,也能提取到正确的标题和 URL。
除了 XPath 外,feature 参数也可以接收关键词,如下图所示:
GNE 会到HTML 去寻找所有包含这个关键词的节点,并通过判断他们的祖先节点来寻找这个关键词所在的标题所在的列表。
什么叫做有限的自动化
有限的自动化就是永远相信人的力量。基于统计学的所有 AI 算法都是不可靠的。
上线时间
有限自动化提取列表页的功能,将会在8月2号上线。