Scrapy并不是刮除整个页面,而是刮除页面的一部分

ymzxtsji  于 2022-11-09  发布在  其他
关注(0)|答案(1)|浏览(166)

我试图从抓取作业配置文件中抓取英国石油公司网站。最初机器人不允许它抓取,但在我初始化ROBOTSTXT_OBEY = False后,它开始工作,但现在它不是抓取整个页面。下面是我的代码:
进口史派瑞类exxonmobilSpider(史派瑞.蜘蛛):这是一个很好的例子,它可以帮助你找到你想要的东西。

def parse(self, response):
    name=response.xpath('//h3[@class="Hit_hitTitle__3MFk3"]')
    print(name)
    print(len(name))[enter image description here][1]

如图所示,xpath给出了h3标记,但是当我运行代码时,得到的是空列表。后来我通过打印所有li或div标记并计算标记总数进行了交叉检查,我发现只有一半或一些标签被刮掉了。任何人都知道为什么Scrapy只刮掉了页面的一部分而不是整个页面。也附上了比较图像。enter image description here您可以看到li标记的总数为55,但现在请检查响应变量“name”的长度。enter image description here

kuuvgm7e

kuuvgm7e1#

希望OP在下一个问题中包含一个最小的可重复示例,这里有一种获取这些作业的方法。请记住,作业是通过页面中的Javascript从API中拉取的,因此您需要使用splash/scrapy-playwright,或者直接刮取API。我们将使用后者。API url是从浏览器的开发工具-网络选项卡中获取的。

import scrapy

class BpscrapeSpider(scrapy.Spider):
    name = 'bpscrape'
    allowed_domains = ['algolianet.com', 'bp.com']
    def start_requests(self):
        headers = {
            'x-algolia-application-id': 'RF87OIMXXP',
            'x-algolia-api-key': 'f4f167340049feccfcf6141fb7b90a5d',
            'Origin': 'https://www.bp.com',
            'content-type': 'application/x-www-form-urlencoded',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36'
        }

        api_url='https://rf87oimxxp-3.algolianet.com/1/indexes/*/queries?x-algolia-agent=Algolia%20for%20JavaScript%20(4.9.1)%3B%20Browser%3B%20JS%20Helper%20(3.4.4)%3B%20react%20(17.0.2)%3B%20react-instantsearch%20(6.11.0)'
        payload = '{"requests":[{"indexName":"candidatematcher_bp_navapp_prod","params":"highlightPreTag=%3Cais-highlight-0000000000%3E&highlightPostTag=%3C%2Fais-highlight-0000000000%3E&filters=type%3A%20Professionals&hitsPerPage=100&query=data%20scientist&maxValuesPerFacet=20&page=0&facets=%5B%22country%22%2C%22group%22%5D&tagFilters="}]}'
        yield scrapy.Request(
            url=api_url,
            headers=headers,
            body=payload,
            callback= self.parse,
            method="POST")
    def parse(self, response):
        data = response.json()['results'][0]['hits']
        for x in data:
            yield x

运行scrapy crawl bpscrape -o bpdsjobs.json得到一个包含所有26个作业的json文件。你需要做一些数据清理,因为json的响应非常全面,包含了很多html标签等等。
有关Scrapy文档,请参见https://docs.scrapy.org/en/latest/

相关问题