【问题标题】:How to simulate xhr request using Scrapy when trying to crawl data from an ajax-based webstie?尝试从基于 ajax 的网站抓取数据时如何使用 Scrapy 模拟 xhr 请求?
【发布时间】:2016-02-18 03:34:46
【问题描述】:

我是使用 Scrapy 抓取网页的新手,不幸的是选择了一个动态的开始...

我已经成功爬取了部分(120 个链接),感谢有人帮助我here,但不是target website 中的链接

经过一番研究,我知道爬ajax web和那些简单的想法没有什么不同:

•打开浏览器开发者工具、网络标签

•转到目标站点

•单击提交按钮并查看发送到服务器的 XHR 请求

•在你的蜘蛛中模拟这个 XHR 请求

最后一个对我来说听起来很模糊---如何模拟 XHR 请求?

我见过有人使用'headers'或'formdata'等参数来模拟。不明白这是什么意思。

这是我的部分代码:

class googleAppSpider(scrapy.Spider):
name = "googleApp"
allowed_domains = ['play.google.com']
start_urls = ['https://play.google.com/store/apps/category/GAME/collection/topselling_new_free?authuser=0']

def start_request(self,response):
    for i in range(0,10): 
        yield FormRequest(url="https://play.google.com/store/apps/category/GAME/collection/topselling_new_free?authuser=0", method="POST", formdata={'start':str(i+60),'num':'60','numChildren':'0','ipf':'1','xhr':'1','token':'m1VdlomIcpZYfkJT5dktVuqLw2k:1455483261011'}, callback=self.parse)

def parse(self,response):
    links = response.xpath("//a/@href").extract()
    crawledLinks = [ ]
    LinkPattern = re.compile("^/store/apps/details\?id=.")
    for link in links:
        if LinkPattern.match(link) and not link in crawledLinks:
            crawledLinks.append("http://play.google.com"+link+"#release")
    for link in crawledLinks:
            yield scrapy.Request(link, callback=self.parse_every_app)

def parse_every_app(self,response):

start_request 似乎在这里没有任何作用。如果我删除它们,蜘蛛仍然会抓取相同数量的链接。

我已经解决了这个问题一个星期...如果您能帮助我,我将不胜感激...

【问题讨论】:

    标签: python ajax scrapy web-crawler form-data


    【解决方案1】:

    试试这个:

    class googleAppSpider(Spider):
        name = "googleApp"
        allowed_domains = ['play.google.com']
        start_urls = ['https://play.google.com/store/apps/category/GAME/collection/topselling_new_free?authuser=0']
    
        def parse(self,response):
            for i in range(0,10): 
                yield FormRequest(url="https://play.google.com/store/apps/category/GAME/collection/topselling_new_free?authuser=0", method="POST", formdata={'start':str(i*60),'num':'60','numChildren':'0','ipf':'1','xhr':'1','token':'m1VdlomIcpZYfkJT5dktVuqLw2k:1455483261011'}, callback=self.data_parse)
    
        def data_parse(self,response):
            item = googleAppItem()
            map = {}
            links = response.xpath("//a/@href").re(r'/store/apps/details.*')
            for l in links:
                if l not in map:
                    map[l] = True
                    item['url'] = l
                    yield item
    

    使用scrapy crawl -o links.csvscrapy crawl -o links.json 抓取蜘蛛,您将获得csv 文件或json 文件中的所有链接。要增加要抓取的页面数,请更改 for 循环的范围。

    【讨论】:

    • 循环不起作用...每次循环,它都会传递给下一个解析函数。
    • “不起作用”是什么意思?你没有得到所有的链接吗?
    • 还有 120 个链接...不是所有链接。有趣的是,如果我删除整个 def 函数,我仍然得到 120
    • 如果你仔细看,每个请求之后的所有链接都是完全不同的。您不能一次获得所有 540 个链接。这就是模拟 xhr 请求的意思。每当您向下滚动时,您的浏览器都会发送不同的 xhr 请求。它不会一次获得所有游戏链接。这正是上面的代码所做的。循环适用于每次向下滚动(每一页)。
    • 谢谢...我完全在 cmd (scrapy crawl) 中运行代码并将结果写入 Json 文件。然后在我将 Json 文件读入数据框后,我发现 df 的长度是 120。这就是我发现只抓取 120 个链接的方式。请告诉我这里出了什么问题...
    猜你喜欢
    • 2017-11-10
    • 1970-01-01
    • 1970-01-01
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-07
    • 1970-01-01
    相关资源
    最近更新 更多