我的任务是从我的供应商处获取最新信息:www.sportsshoes.com。
我面临的问题是,尽管Crawl Spider访问了类别页面的每个页面,但它只提供了第一页的返回数据。如果我尝试独立地抓取每个页面也是如此,即使我指定它来刮取类别的第三页它只返回第一页的结果。
我的代码:
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.selector import HtmlXPathSelector
from scrapy.spider import BaseSpider
from sportshoes.items import SportshoesItem
import urlparse
from scrapy.http.request import Request
class MySpider(CrawlSpider):
name = "tennis"
allowed_domains = ["sportsshoes.com"]
start_urls = ["http://www.sportsshoes.com/products/shoe/tennis/",
"http://www.sportsshoes.com/products/shoe/tennis#page=2",
"http://www.sportsshoes.com/products/shoe/tennis#page=3"]
rules = (Rule (SgmlLinkExtractor(allow=(),restrict_xpaths=('//div[@class="product-detail"]',))
, callback="parse_items", follow= True,),)
def parse_items(self, response):
hxs = HtmlXPathSelector(response)
titles = hxs.select("//html")
items = []
for titles in titles:
item = SportshoesItem()
item ["productname"] = titles.select("//h1[@id='product_title']/span/text()").extract()
item ["Size"] = titles.select('//option[@class="sizeOption"]/text()').extract()
item ["SKU"] = titles.select("//div[@id='product_ref']/strong/text()").extract()
items.append(item)
return(items)
PS:我也使用过这种方法:
rules = (Rule (SgmlLinkExtractor(allow=(),restrict_xpaths=('//div[@class="paginator"]',)), follow= True),
Rule (SgmlLinkExtractor(restrict_xpaths=('//div[@class="hproduct product"]',))
, callback="parse_items", follow= True),)
答案 0 :(得分:1)
Scrapy认为这些#page=2
和#page=3
链接是同一页面。对于scrapy,它们被解释为页内命名锚引用。所以他们没有下载两次。
在某些Javascript的帮助下,它们在浏览器中意味着什么。
当您点击“下一页”页面链接时检查浏览器的Inspect / Developer工具中发生的情况时,您会注意到AJAX调用http://www.sportsshoes.com/ajax/products/search.php
作为HTTP POST请求,并且参数类似于以下内容:
page:3
search-option[show]:20
search-option[sort]:relevency
q:
na:YTowOnt9
sa:YToyOntpOjA7YToyOntzOjM6ImtleSI7czoxMzoicHJvZHVjdF9jbGFzcyI7czo2OiJ2YWx1ZTEiO3M6NDoic2hvZSI7fWk6MTthOjI6e3M6Mzoia2V5IjtzOjU6InNwb3J0IjtzOjY6InZhbHVlMSI7czo2OiJ0ZW5uaXMiO319
aav:YTowOnt9
layout:undefined
对这些AJAX调用的响应是嵌入包含来自下一页的HTML页面的XML文档,最终将替换第一页产品。
<?xml version="1.0" encoding="UTF-8" ?>
<response success="true">
<message>success</message>
<value key="html"><![CDATA[<div id="extra-data" data-extra-na="YTowOnt9"...
您必须模拟这些AJAX调用才能获取所有页面的数据。请注意,这些POST请求包含一个特殊标题:X-Requested-With: XMLHttpRequest
要告诉scrapy发送POST请求,您可以在创建Requests
个对象时使用"method" parameter。