我的爬行蜘蛛和分页的问题。仅提取第一页的值

时间:2014-06-26 06:43:07

标签: pagination web-scraping scrapy

我的任务是从我的供应商处获取最新信息: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),)

1 个答案:

答案 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