抓取一些Facebook数据,但不是全部? Scrapy / Splash / Python

时间:2018-12-31 02:59:25

标签: python facebook scrapy splash

我有一个看起来像这样的蜘蛛

import scrapy
from scrapy_splash import SplashRequest

class BarkbotSpider(scrapy.Spider):
    name = 'barkbot'
    start_urls = [
        'http://www.facebook.com/pg/TheBarkFL/events/?ref=page_internal/'
    ]
    custom_settings = {
        'FEED_URI': 'output/barkoutput.json'
    }

    def start_requests(self):
        for url in self.start_urls:
            yield SplashRequest(
                url,
                self.parse,
            )

    def parse(self, response):
        for href in response.css("div#upcoming_events_card a::attr(href)").extract():
            yield response.follow(href, self.parse_concert)

    def parse_concert(self, response):
        concert = {

            "headliner" : response.xpath(
                "//h1[@id='seo_h1_tag']/text()"
            ).extract_first(),

            "venue" : "The Bark",
            "venue_address" : "507 All Saints St.",
            "venue_website" : "https://www.facebook.com/TheBarkFL",

            "date_time" : response.xpath(
                "//li[@id='event_time_info']//text()"
            ).extract(),

            "notes" : response.xpath(
                "//div[@data-testid='event-permalink-details']/span/text()"
            ).extract()

        }

        if concert['headliner']:
            yield concert

我跑了蜘蛛,它成功完成了。但是所有返回的“ notes”和“ date_time”键都是空列表。我对注释一特别困惑,因为这似乎相当简单,除非xpath不能将data-testid用作属性。但是,我正在成功刮掉车顶篷钥匙,因此很明显,我正在连接到每个页面。

我是第一次使用JavaScript生成的内容,因此也没有使用Splash,但是我设法让另一只蜘蛛成功地工作了,而不仅仅是在Facebook上。有什么作用?

1 个答案:

答案 0 :(得分:1)

  

除非xpath不能将data-testid用作属性

不是,不是吗?我刚刚使用Scrapy 1.5.1进行了检查,并且您的xpath与示例文档匹配良好。它甚至与该文档中的其他data-testid属性相匹配,因此我很确定您遇到了竞争状况,因为event-permalink-details不会出现在HTML中;它是从XHR调用加载到他们的graphql端点的。由于Splash,您的情况可能很好,但是如果选择器不匹配,则该选择器将在XHR解析之前运行。我对Splash知之甚少,无法帮助解决这种情况。


我不知道您的date_time问题的答案,但我实际上打赌您真正想要的是.xpath('//li[@id="event_time_info"]//@content'),因为其中包含2019-01-03T17:30:00-08:00 to 2019-01-03T20:30:00-08:00,它似乎比字符串的含义更好不合格的text()匹配