【问题标题】:Looping through pages of Web Page's Request URL with Scrapy使用 Scrapy 循环浏览网页的请求 URL 页面
【发布时间】:2020-04-25 20:46:55
【问题描述】:

我希望调整本教程 (https://medium.com/better-programming/a-gentle-introduction-to-using-scrapy-to-crawl-airbnb-listings-58c6cf9f9808) 以抓取此小型房屋列表站点:https://tinyhouselistings.com/

本教程使用请求 URL 来获得一个非常完整和干净的 JSON 文件,但仅针对第一页这样做。似乎循环浏览我的 tinyhouselistings 请求 url 的 121 页应该非常简单,但我无法得到任何工作。本教程不会遍历请求 url 的页面,而是使用 scrapy splash,在 Docker 容器中运行以获取所有列表。我愿意尝试,但我只是觉得应该可以遍历这个请求 url。

这仅输出我的项目的 tinyhouselistings 请求 url 的第一页:

import scrapy

class TinyhouselistingsSpider(scrapy.Spider):
    name = 'tinyhouselistings'
    allowed_domains = ['tinyhouselistings.com']
    start_urls = ['http://www.tinyhouselistings.com']

    def start_requests(self):
        url = 'https://thl-prod.global.ssl.fastly.net/api/v1/listings/search?area_min=0&measurement_unit=feet&page=1'

        yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        _file = "tiny_listings.json"
        with open(_file, 'wb') as f:
                f.write(response.body)

我试过了:

class TinyhouselistingsSpider(scrapy.Spider):
    name = 'tinyhouselistings'
    allowed_domains = ['tinyhouselistings.com']
    start_urls = ['']

def start_requests(self):
        url = 'https://thl-prod.global.ssl.fastly.net/api/v1/listings/search?area_min=0&measurement_unit=feet&page='
        for page in range(1, 121):
                self.start_urls.append(url + str(page))
                yield scrapy.Request(url=start_urls, callback=self.parse)

但我不确定如何传递 start_urls 来解析,以便将响应写入脚本末尾正在写入的 json。

任何帮助将不胜感激!

【问题讨论】:

    标签: scrapy request


    【解决方案1】:

    去掉allowed_domains = ['tinyhouselistings.com'],因为thl-prod.global.ssl.fastly.net这个url会被Scrapy过滤掉

    由于您使用的是start_requests方法,所以您不需要start_urls,您只能使用其中一个

    import json
    
    class TinyhouselistingsSpider(scrapy.Spider):
        name = 'tinyhouselistings'
        listings_url = 'https://thl-prod.global.ssl.fastly.net/api/v1/listings/search?area_min=0&measurement_unit=feet&page={}'
    
        def start_requests(self):
            page = 1
            yield scrapy.Request(url=self.listings_url.format(page),
                meta={"page": page},
                callback=self.parse)
    
        def parse(self, response):
            resp = json.loads(response.body)
            for ad in resp["listings"]:
                yield ad
    
    
            page = int(response.meta['page']) + 1
            if page < int(listings['meta']['pagination']['page_count'])
                yield scrapy.Request(url=self.listings_url.format(page),
                    meta={"page": page},
                    callback=self.parse)
    

    从终端,使用 save scraped data to a JSON file 运行蜘蛛

    scrapy crawl tinyhouselistings -o output_file.json
    

    【讨论】:

    • 非常感谢 Umair!这很有帮助:) 程序现在正在遍历页面,但返回的项目看起来是一个字符串:ERROR: Spider must return Request, BaseItem, dict or None, got 'str' in &lt;GET https://thl-prod.global.ssl.fastly.net/api/v1/listings/search?area_min=0&amp;measurement_unit=feet&amp;page=12&gt; 我认为问题在于循环的广告和列表,我尝试返回一个 dict str...有什么建议吗?
    • @Erin 看到我编辑的答案,它应该是'listings[“listings”]'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多