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