当前位置: 代码迷 >> python >> Scrapy-在Shell和Spider中处理Ajax连续响应数据
  详细解决方案

Scrapy-在Shell和Spider中处理Ajax连续响应数据

热度:58   发布时间:2023-06-13 17:02:17.0

我正在尝试抓取ajax请求后加载的数据。

例如,此youtube页面的前30个视频以html格式显示,然后用户必须单击“加载更多”按钮,该按钮会触发ajax并获得更多结果。

我可以获得ajax链接,但是使用Scrapy功能提取剩余数据/“分页”的最佳方法是什么?

启动shell:

scrapy shell https://www.youtube.com/user/testedcom/videos

获取Ajax延续的网址:

continuation_url = response.xpath('//*[@class="yt-uix-button yt-uix-button-size-default yt-uix-button-default load-more-button yt-uix-load-more browse-items-load-more-button"]/@data-uix-load-more-href').extract()[0]
url = "https://www.youtube.com/user/testedcom/videos" + continuation_url

从ajax调用获取新数据:

fetch(url)

...但是从这里我不确定如何处理数据。 它与运行scrapy shell的原始响应格式不同。 它似乎不太像JSON那样加载。 我认为scrapy专门为此提供了一些东西,但是在文档中找不到它。

编辑我可以通过执行以下操作获取html内容:

import json
response_json = json.loads(response.body_as_unicode())
html = response_json['content_html']

但是然后我将不得不使用正则表达式从此Unicode中提取所需的数据,而不是内置xpath选择器,后者更加方便。

这是Scrapy Selector的文档: ://doc.scrapy.org/en/1.1/topics/selectors.html

我遇到了同样的问题。 然后由Selector处理。 您可以通过响应或字符串构造选择器,然后可以使用“ xpath”。

另外,您可以使用try...except...识别响应类型(html或json)

def parse(self, response):
    try:
        jsonresponse = json.loads(response.body_as_unicode())
        html = jsonresponse['content_html'].strip()
        sel = Selector(text=html)
    except:
        sel = Selector(response=response)

    entries = sel.xpath(
        '//li[contains(@class,"feed-item-container")]')
    for entry in entries:
        try:
            title = entry.xpath('.//h3/a/text()').extract()[0]
            item = YoutubeItem()
            item['title'] = title
            yield item
        except Exception as err:
            continue

    try:
        jsonresponse = json.loads(response.body_as_unicode())
        sel = Selector(text=jsonresponse['load_more_widget_html'])
    except:
        sel = Selector(response=response)
    try:
        url = "https://www.youtube.com" + \
            sel.xpath(
                '//button[contains(@class,"load-more-button")]/@data-uix-load-more-href').extract()[0]
        req = scrapy.Request(url, callback=self.parse)
        yield req
    except:
        self.log('Scawl completed.')

获得html内容后,您可以初始化一个Selector对象以使用xpath选择器:

from scrapy.selector import Selector
import json

response_json = json.loads(response.body_as_unicode())
html = response_json['content_html']
sel = Selector(text=html)
for url in sel.xpath('//@href').extract():
    yield Request(url, callback=self.somecallbackfunction)
  相关解决方案