2015-07-05 104 views
0

我想用Scrapy刮 - www.paytm.com。该网站使用AJAX请求,以XHR的形式显示搜索结果。Scrapy刮板问题

我设法追踪到XHR,而AJAX响应对于JSON是SIMILAR,但实际上并不是JSON。

这是XHR请求之一的链接 - https://search.paytm.com/search/?page_count=2&userQuery=tv&items_per_page=30&resolution=960x720&quality=high&q=tv&cat_tree=1&callback=angular.callbacks._6。如果您正确查看网址,则参数 - page_count - 负责显示不同页面的结果,而参数userQuery - 负责传递到网站的搜索查询。

现在,如果您看到正确的响应。它实际上并不是JSON,只是看起来类似于JSON(我在http://jsonlint.com/上实现了它)。我想使用SCRAPY (SCRAPY仅仅是因为它是一个框架,它比使用像BeautifulSoup这样的其他库更快,因为使用它们来创建一个刮擦速度如此之快的刮板会花费很大的精力 - 是我想使用Scrapy的唯一原因。)

现在,这是我的代码片段,我用来提取从URL的JSON响应 - :

jsonresponse = json.loads(response.body_as_unicode()) 
    print json.dumps(jsonresponse, indent=4, sort_keys=True) 

上执行的代码,它引发我一个错误,述明:

2015-07-05 12:13:23 [scrapy] INFO: Scrapy 1.0.0 started (bot: scrapybot) 
2015-07-05 12:13:23 [scrapy] INFO: Optional features available: ssl, http11 
2015-07-05 12:13:23 [scrapy] INFO: Overridden settings: {'DEPTH_PRIORITY': 1, 'SCHEDULER_MEMORY_QUEUE': 'scrapy.squeues.FifoMemoryQueue', 'SCHEDULER_DISK_QUEUE': 'scrapy.squeues.PickleFifoDiskQueue', 'CONCURRENT_REQUESTS': 100} 
2015-07-05 12:13:23 [scrapy] INFO: Enabled extensions: CloseSpider, TelnetConsole, LogStats, CoreStats, SpiderState 
2015-07-05 12:13:23 [scrapy] INFO: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, MetaRefreshMiddleware, HttpCompressionMiddleware, RedirectMiddleware, CookiesMiddleware, ChunkedTransferMiddleware, DownloaderStats 
2015-07-05 12:13:23 [scrapy] INFO: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware 
2015-07-05 12:13:23 [scrapy] INFO: Enabled item pipelines: 
2015-07-05 12:13:23 [scrapy] INFO: Spider opened 
2015-07-05 12:13:23 [scrapy] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min) 
2015-07-05 12:13:23 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023 
2015-07-05 12:13:24 [scrapy] DEBUG: Crawled (200) <GET https://search.paytm.com/search/?page_count=2&userQuery=tv&items_per_page=30&resolution=960x720&quality=high&q=tv&cat_tree=1&callback=angular.callbacks._6> (referer: None) 
2015-07-05 12:13:24 [scrapy] ERROR: Spider error processing <GET https://search.paytm.com/search/?page_count=2&userQuery=tv&items_per_page=30&resolution=960x720&quality=high&q=tv&cat_tree=1&callback=angular.callbacks._6> (referer: None) 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 577, in _runCallbacks 
    current.result = callback(current.result, *args, **kw) 
    File "Startup App/SCRAPERS/paytmscraper_scrapy/paytmspiderscript.py", line 111, in parse 
    jsonresponse = json.loads(response.body_as_unicode()) 
    File "/usr/lib/python2.7/json/__init__.py", line 338, in loads 
    return _default_decoder.decode(s) 
    File "/usr/lib/python2.7/json/decoder.py", line 366, in decode 
    obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 
    File "/usr/lib/python2.7/json/decoder.py", line 384, in raw_decode 
    raise ValueError("No JSON object could be decoded") 
ValueError: No JSON object could be decoded 
2015-07-05 12:13:24 [scrapy] INFO: Closing spider (finished) 
2015-07-05 12:13:24 [scrapy] INFO: Dumping Scrapy stats: 
{'downloader/request_bytes': 343, 
'downloader/request_count': 1, 
'downloader/request_method_count/GET': 1, 
'downloader/response_bytes': 6483, 
'downloader/response_count': 1, 
'downloader/response_status_count/200': 1, 
'finish_reason': 'finished', 
'finish_time': datetime.datetime(2015, 7, 5, 6, 43, 24, 733187), 
'log_count/DEBUG': 2, 
'log_count/ERROR': 1, 
'log_count/INFO': 7, 
'response_received_count': 1, 
'scheduler/dequeued': 1, 
'scheduler/dequeued/memory': 1, 
'scheduler/enqueued': 1, 
'scheduler/enqueued/memory': 1, 
'spider_exceptions/ValueError': 1, 
'start_time': datetime.datetime(2015, 7, 5, 6, 43, 23, 908135)} 
2015-07-05 12:13:24 [scrapy] INFO: Spider closed (finished) 

现在,我的问题,我如何使用Scrapy刮取这样的响应?如果需要其他代码,请随时在评论中提问。我会甘心给它!

请提供与此相关的完整代码。这将不胜感激!也许一些操纵JSON响应(来自python)(类似于字符串比较)也适用于我,如果它可以帮助我刮这个!

P.S:我无法每次手动(使用手)修改JSON响应,因为这是网站给出的响应。所以,请建议一个编程(pythonic)的方式来做到这一点。最好,我想使用Scrapy作为我的框架。

回答

3

如果你看看非JSON结果,很明显它包含一个JSON。

如果您从响应中删除typeof angular.callbacks._6 === "function" && angular.callbacks._6(的初始部分,并在最后删除);,您将得到一个有效的JSON,您可以使用JSONLint进行验证。

最终的解决办法是找到的{}的首次和最后出现分别在响应并提取文本中的(包括那些大括号的),并使用与json.loads而不是整个结果。

+0

不必手动提取JSON。从请求中删除'&callback = angular.callbacks._6' – 3zzy

0

变化:

https://search.paytm.com/search/?page_count=2&userQuery=tv&items_per_page=30&resolution=960x720&quality=high&q=tv&cat_tree=1&callback=angular.callbacks._6 

到:

https://search.paytm.com/search/?page_count=2&userQuery=tv&items_per_page=30&resolution=960x720&quality=high&q=tv&cat_tree=1 

..和你有JSON。

2

Paytm提供JSON数据,请

https://catalog.paytm.com/v1//g/electronics/mobile-accessories/mobiles

目录页返回上传.json数据,其中包括产品名称,产品链接,报价,实际价格和图像数据等。

如何获取某个类别的数据:

在上面的url中,您可以看到catalog.paytm.com/v1//g/,它是所有url的泛型,您需要用以下格式替换url的其他部分。

菜单项目>类别>子类别。

其中电子是菜单项,手机配件是手机类,手机类是手机配件的子类。

当您以上述格式运行url时,paytm将返回json数据,您可以使用以下参数查询更多页面的paytm。

PAGE_COUNT和items_per_count

例如:catalog.paytm.com/v1//g/electronics/mobile-accessories/mobiles?page_count=2 & items_per_count = 30

在grid_layout JSON数据搜索

,如果它不可用,该页面没有项目,则可以循环出来,否则处理json数据并阅读产品详细信息。