在网页片段内直观标注——以B站评论采集为例

2024-9-18 17:31| 发布者: Fuller| 查看: 290| 评论: 0

摘要: B站上的用户评论内容放在一个多层嵌套的网页片段(HTML新技术)中,在定义规则模式下,如果点击用户评论中的任何信息,比如,某条评论的发布日期,只能定位到最外层网页片段,内部的内容一开始是生成不了DOM树的,所 ...

1. 问题

用作测试的爬虫任务:B站评论列表采集测试

B站上的用户评论内容放在一个多层嵌套的网页片段(HTML新技术)中,在定义规则模式下,如果点击用户评论中的任何信息,比如,某条评论的发布日期,只能定位到最外层网页片段,内部的内容一开始是生成不了DOM树的,所以就没法定位到具体的内容节点。如下图:

从V12.3.0版本开始,我们将逐步解决这个问题,实现定位到网页片段内部,并能为内部节点生成path,并根据path搜索网页上的节点。

2. 直观定位

首先要设法能够定位到网页片段内部。如下图,在代表网页片段的网页区域选择右键鼠标菜单“开启标注”,就能允许定位到网页片段内部。这个操作也可以在DOM树上做,选择代表网页片段的那个DOM节点,同样使用鼠标右键菜单“开启标注”。

开启以后,再把鼠标移动用户评论区域,就会发现蓝色背景覆盖的区域变小了,不再是整个评论区,而是具体某个人的评论。如下图:

如果在浏览器上点击那个区域,在DOM树上就能定位到网页片段内部代表这个用户区域的DOM节点。

B站用户评论区有大量的嵌套网页片段,如果想精确定位到某个用户发表评论的时间,需要执行多层“开启标注”,才能把发表时间、点赞数等等细粒度的内容剥出来。

3. 生成path

自定义path的含义扩展了,以前版本自定义的只有xpath,从V12.3.0版本开始,自定义path包括xpath和css选择器。

以前版本的path是扩展了的xpath,即使用<context></context>标签括起来的xpath定位iframe的位置,然后用最前面的没有括起来的部分定位到iframe内的DOM元素。

从V12.3.0开始,如果要采集网页片段内的内容,需要将xpath替换成扩展了的css选择器。所谓“扩展”,就是在普通的css选择器中增加<gs_root></gs_root>标签括起来的css选择器。在<gs_root></gs_root>内部的css选择器可以定位到一个网页片段整体,没有被<gs_root></gs_root>括起来的css选择器可以定位到一个DOM元素。

例如:上图的发布日期的css选择器是

<gs_root>div.comment > bili-comments</gs_root><gs_root>div#feed > bili-comment-thread-renderer + bili-comment-thread-renderer</gs_root><gs_root>bili-comment-renderer#comment</gs_root><gs_root>div#footer > bili-comment-action-buttons-renderer</gs_root>div#pubdate

定位DOM元素的时候从左到右一层层进入多级网页片段,最后用div#pubdate定位到最内层网页片段中的发布日期。

4. 直观标注和自定义xpath的变化

目前,针对网页片段内的内容,只能使用自定义path定义采集规则,不能通过内容映射或直观标注定义采集规则。

如果想采集网页片段内的内容,将整个网页片段映射给抓取内容,而不能将网页片段内的网页内容映射给抓取内容。

然后给抓取内容自定义xpath,而且选择专用定位模式,定位path只需要输入一个点号,内容path使用生成的css选择器。

如果是嵌套整理箱,跟xpath类似,css选择器应该也是相对的,即抓取内容的path相对于容器的path,不能使用完整的从html顶层节点开始定位的path。

5. 自定义path

假设我们要采集评论以及评论的回复,需要定义一个嵌套的整理箱,如下图。

“评论列表”应该对应到多条评论,内部的“回复列表”应该为每条评论对应到多条的回复。他们都是容器节点,其包含的“评论作者”,“评论内容”,“回复作者”,“回复内容”才是要采集的内容,应该对应到具体的网页内容。

5.1 内容映射阶段

对于普通网页,只需要为采集内容做内容映射或者直观标注就行,此案例的采集内容有:“评价作者”、“评价内容”、“回复作者”,“回复内容”四个。

对于网页片段内的内容采集,我们不能直接做内容映射,否则既采集不到内容,还在以后加载分析规则的时候加载失败。所以,我们要对这四个抓取内容做特殊的映射。如上图,都用整个网页片段对应的那个DOM节点做内容映射。也就是说,只能用网页片段内部的DOM节点做内容映射。

做完内容映射以后,点击测试按钮,可以看到其他内容都采集到了,但是,评论列表容器内的所有内容都没有采集到。

下面就要为他们自定义path。

5.2 自定义path阶段

我们首先为“评论列表”自定义path(也就是css选择器)定位到多条评论,然后再为内部的“评论作者”自定义相对于“评论列表”的定位path。其他抓取内容和内部嵌套的整理箱也是用类似方法得到的定位path。

利用前面第三章讲的方法,为整理箱中的“评论列表”、“评价作者”、“评价内容”、“回复列表”、“回复作者”,“回复内容”都自定义path。

5.2.1 评论列表的path

如下图,先为评论列表生成path。

此前已经为网页片段开启了标注,鼠标浮到第一条评论区域(上图红框内),点击鼠标,可以看到下面DOM树定位到一个DOM节点。选择“任何标志”,生成css选择器path。为了验证这个path是正确的,可以点击右边放大镜图标,将会显示搜索到多少条评论。

把这个生成的path拷贝下来,双击整理箱中的“评论列表”,开启自定义path,输入进去。因为“评论列表”是一个容器,而不是普通的抓取内容,所以自定义path不需要选择兼用定位还是专用定位。

生成的path是:

<gs_root>div.comment > bili-comments</gs_root>div#feed > bili-comment-thread-renderer

注意要做手工修改:这里需要为生成的path做一点手工修改,如下,为最后一段path也套上<gs_root></gs_root>:

<gs_root>div.comment > bili-comments</gs_root><gs_root>div#feed > bili-comment-thread-renderer</gs_root>

并不是每次都需要加上<gs_root></gs_root>,加上这个标签是告诉爬虫:为“评论列表”定位到的DOM节点不是普通的元素,而是一个网页片段,“评论列表”内的“评论作者”等抓取内容要在这个网页片段内部采集数据。相反,如果不是在网页片段内部采集数据,而是在一个普通html元素内部采集数据,就不用加<gs_root></gs_root>。

注意:优先使用“任何标志”,对于css选择器来说,这种类型最适合。

5.2.2 评论作者的path

这个网页有很多层网页片段,经过一系列开启标注以后,终于可以精确选中评论作者这个网页区域了,点击“任何标志”,生成path。如下图,蓝框刚好套在评论作者上,说明这里是最精准的。

把生成的path拷贝出来,如下:

<gs_root>div.comment > bili-comments</gs_root><gs_root>div#feed > bili-comment-thread-renderer</gs_root><gs_root>bili-comment-renderer#comment</gs_root><gs_root>div#header > bili-comment-user-info</gs_root>div#user-name > a

这个path不能直接设置给“评论作者”,因为要变成相对于“评论列表”的path。

那么,把评论列表的path也拷贝过来比较一下:

<gs_root>div.comment > bili-comments</gs_root>div#feed > bili-comment-thread-renderer

可以看到,前面部分是相同的,只需要截掉前面相同的部分,保留以下部分:

<gs_root>bili-comment-renderer#comment</gs_root><gs_root>div#header > bili-comment-user-info</gs_root>div#user-name > a

把截取留下来的path部分输入到上图的“内容xpath”那里,而定位xpath那里输入了.号。这个.号是怎么来的?这是来自爬虫自动生成的采集规则。如下图:

我们点击测试按钮,切换到“采集规则”那里,看到为评论作者自动生成的规则那里就是一个.号,把这个部分拷贝过来作为定位xpath就对了。定位xpath是在加载分析规则的时候使用,并不在采集内容的时候使用。为了以后能够加载分析规则,就需要正确输入定位xpath。

5.2.3 回复列表的path

回复列表是整理箱中又一层嵌套的容器,不过生成css选择器和截取需要的部分是一样的。此后,为“回复作者”生成path的时候,就要相对于回复列表的path进行截取。

下图可见,经过一系列“开启标注”以后,终于可以选中每一条回复了,对应下图红框的区域,在DOM树上对应多个相同类型的DOM节点。

6. 采集元素节点中的属性和text节点

CSS 选择器只能定位到html元素节点,如果要采集元素中的属性或者元素下面的text节点,需要生成的定位表达式的最右边一段后面增加:

<gs_xpath>一个xpath表达式</gs_xpath>

在这之前,爬虫软件已经使用CSS选择器定位到了某个元素,接下来使用上述表达式,以定位到的元素节点为参照,可以进一步定位到其他元素节点、元素的属性节点、元素的文本节点。

比如:

<gs_xpath>@href</gs_xpath>:可以用来采集href属性

<gs_xpath>text()[5]</gs_xpath>:可以用来采集元素中的第5个text节点的内容。


鲜花

握手

雷人

路过

鸡蛋

最新评论

GMT+8, 2024-10-6 15:17