Проблемы с моим пауком обхода и нумерацией страниц. Извлекается только значение с первой страницы

#pagination #web-scraping #scrapy

#разбивка на страницы #очистка веб-страниц #scrapy

Вопрос:

Моя задача — получать обновления от одного из моих поставщиков: www.sportsshoes.com .

Проблема, с которой я сталкиваюсь, заключается в том, что, несмотря на то, что паук обхода посещает каждую страницу страницы категории, он возвращает только данные с первой страницы. Это также имеет место, если я пытаюсь очистить каждую страницу независимо, т.Е. Даже если я назначу ее для очистки третьей страницы категории, она возвращает результаты только с первой страницы.

Мой код:

 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:

#page=2 Scrapy считает, что они и #page=3 ссылки являются одной и той же страницей. Для scrapy они интерпретируются как ссылки с именем привязки на странице. Поэтому они не загружаются дважды.

Они что-то значат в браузере, хотя и с помощью некоторого Javascript.

Когда вы проверяете, что происходит в инструменте проверки / разработчика вашего браузера при нажатии на ссылки «Следующие» страницы, вы заметите вызовы 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 представляют собой XML-документы, встраивающие HTML, содержащие страницы со следующих страниц, которые в конечном итоге заменят продукты первой страницы.

 <?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 объектов.