Scrapy + Splash:在内部html中抓取元素

时间:2017-06-20 15:47:28

标签: xpath scrapy scrapy-splash

我正在使用Scrapy + Splash来抓取网页并尝试从Google广告横幅广告和其他广告中提取数据,而且我很难让scrapy跟随xpath进入它们。

我正在使用Scrpay-Splash API来呈现网页,以便加载脚本和图片并截取屏幕截图,但似乎Google广告横幅是由JS脚本创建的,然后将其内容插入到新的html文档中网页中的iframe,如下所示:The red area is the iframe container, the blue shows the link I want to extract

Splash确保代码被渲染,所以我没有遇到scrapy在脚本中读取脚本的内容而不是它产生的html的常见问题 - 但我似乎无法找到一种方法来指示到达我需要的元素节点所需的XPath(广告的href链接)。

如果我检查谷歌中的元素并复制它的xpath,它只是给我//*[@id="aw0"],如果iframe的html就在这里,我觉得它会起作用,但无论我怎么写它都会返回空白我觉得这可能是因为XPath没有优雅地处理堆叠在html文档中的html文档。

包含Google广告代码的iframe的XPath是 //*[@id="google_ads_iframe_/87824813/hola/blogs/home_0"] {数字是常数}。

有没有办法将这些XPath叠加在一起让scrapy跟踪我需要的容器?或者我应该以其他方式直接解析Splash响应对象,我不能依赖于Response.Xpath / Response.CSS吗?

2 个答案:

答案 0 :(得分:3)

问题是iframe内容不会作为html的一部分返回。您可以尝试直接获取iframe内容(通过其src),也可以使用iframes = 1选项的render.json端点:

# ...
    yield SplashRequest(url, self.parse_result, endpoint='render.json', 
                        args={'html': 1, 'iframes': 1})

def parse_result(self, response):
    iframe_html = response.data['childFrames'][0]['html']
    sel = parsel.Selector(iframe_html)
    item = {
        'my_field': sel.xpath(...),
        # ...  
    }
截至Splash 2.3.3,

/execute端点不支持获取iframe内容。

答案 1 :(得分:0)

处理iframe的另一种方法是(主页面响应):

    urls = response.css('iframe::attr(src)').extract()
    for url in urls :
            parse the url

这样iframe被解析就像是普通页面一样, 但目前我无法将主页面中的cookie发送到iframe内的html,这是一个问题