【问题标题】:Scraper only getting first item?刮刀只得到第一个项目?
【发布时间】:2022-01-25 02:03:31
【问题描述】:

我的爬虫只得到下面的第一个列表。如何让它获取列表中的所有地址?这是一个简单的程序,可以提取下面链接中的地址。

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy_splash import SplashRequest


class Listings2Spider(CrawlSpider):
    name = 'listings2'
    allowed_domains = ['www.realtor.ca']
    user_agent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"

    script = '''
    function main(splash, args)
        splash.private_mode_enabled = false
        url = args.url
        assert(splash:go(url))
        assert(splash:wait(3))
        return splash:html()
    end
    '''

    def start_requests(self):
        yield SplashRequest(url='https://www.realtor.ca/map#ZoomLevel=13&Center=43.686631%2C-79.339824&LatitudeMax=43.75741&LongitudeMax=-79.25894&LatitudeMin=43.61577&LongitudeMin=-79.42071&view=list&Sort=6-D&PGeoIds=g20_dpz8de7m&GeoName=East%20York%2C%20Toronto%2C%20ON&PropertyTypeGroupID=1&PropertySearchTypeId=1&TransactionTypeId=2&Currency=CAD',
                             headers={'User-Agent': self.user_agent}, callback=self.parse_item, endpoint="execute", args={'lua_source': self.script})

    rules = (
        Rule(LinkExtractor(restrict_xpaths="//div[@class='cardCon']"), callback='parse_item', follow=True, process_request='set_user_agent'),
    )
    def set_user_agent(self, request):
        request.headers['User-Agent'] = self.user_agent
        return request

    def parse_item(self, response):
        yield {
            'Address': response.xpath("//div[@class='listingCardAddress']/text()").get()
        }

【问题讨论】:

    标签: web-scraping scrapy scrapy-splash


    【解决方案1】:

    似乎应用了速率限制,我可以自动化 api 调用并避免使用浏览器自动化,但网站似乎在几页后阻止了请求。请注意,这样做您每页最多可以获得 100 个结果,这将(当它工作时!)更快,并且您从 json 获得的详细信息比从前端 html 获得的更多。

    import requests
    
    s = requests.Session()
    home_url = 'https://www.realtor.ca/map#ZoomLevel=13&Center=43.686631%2C-79.339824&LatitudeMax=43.75741&LongitudeMax=-79.25894&LatitudeMin=43.61577&LongitudeMin=-79.42071&view=list&Sort=6-D&PGeoIds=g20_dpz8de7m&GeoName=East%20York%2C%20Toronto%2C%20ON&PropertyTypeGroupID=1&PropertySearchTypeId=1&TransactionTypeId=2&Currency=CAD'
    step = s.get(home_url)
    print(step)
    
    url = 'https://api2.realtor.ca/Listing.svc/PropertySearch_Post'
    
    headers = {
        'accept':'*/*',
        'accept-encoding':'gzip, deflate, br',
        'content-type':'application/x-www-form-urlencoded; charset=UTF-8',
        'origin':'https://www.realtor.ca',
        'referer':'https://www.realtor.ca/',
        'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36'
        }
    
    output = []
    for page in range(1,5):
    
        payload = {
            'ZoomLevel':'13',
            'LatitudeMax':'43.75741',
            'LongitudeMax':'-79.25894',
            'LatitudeMin':'43.61577',
            'LongitudeMin':'-79.42071',
            'Sort':'6-D',
            'PropertyTypeGroupID':'1',
            'PropertySearchTypeId':'1',
            'TransactionTypeId':'2',
            'Currency':'CAD',
            'RecordsPerPage':'100',
            'ApplicationId':'1',
            'CultureId':'1',
            'Version':'7.0',
            'CurrentPage': str(page)
            }
    
        post = s.post(url,headers=headers,data=payload).json()
        results = len(post['Results'])
        print(f'Scraping page: {page}, results: {results}')
    
        for listing in post['Results']:
            print(listing['Id'],listing['Property']['Price'])
    

    【讨论】:

    • 有趣。我正在上一门关于刮擦和飞溅的课程。你不倾向于使用这些工具吗?
    • 您是如何获得 API 链接的?抱歉,我是新手。
    • 用那些工具就好了,scrapy很强大,可以像我一样使用。我只是尽量不使用自动化浏览器,因为开发起来非常缓慢和麻烦。我通过打开浏览器的开发人员工具 - 网络选项卡 - 获取/Xhr 并刷新页面找到了该 API,这将显示所有后端 api 调用,然后如果您选择“下一页”,则可以查看哪个传递了数据“在网站上,它将显示数据的来源。然后我在上面的脚本中重新创建了调用
    • 非常感谢。我不知道。我试图在scrapy中复制这项工作,但我正在让它工作!你介意快速浏览一下吗? github.com/ryanshrott/scraping/blob/master/realtor2/realtor2/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-01
    • 1970-01-01
    • 2020-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多