Я написал scrawlspider для сканирования сайта со структурой, такой как страница категории> страница типа> страница списка> страница элемента.На странице категорий есть много категорий машин, у каждой из которых есть страница типа с большим количеством типов, у каждого из различных типов есть список элементов, и, наконец, у каждой машины есть страница с информацией о ней.
У моего паука есть правило для перехода с домашней страницы на страницу категории, где я определяю страницу обратного вызова parsecatpage, она генерирует элемент, захватывает категорию и выдает новый запрос для каждой категории на странице.Я передаю элемент и имя категории с помощью request.meta и указываю, что обратный вызов - это страница parsetype.
Parsetypepage получает элемент из response.meta, затем выдает запросы для каждого типа и передает элемент, а также объединяет категориюи введите вместе с ним в request.meta.Обратным вызовом является parsemachinelist.
Parsemachinelist получает элемент из response.meta, затем выдает запросы для каждого элемента в списке и передает элемент, категорию / тип, описание через request.meta окончательному обратному вызову parsemachine.Это получает мета-атрибуты и заполняет все поля в элементе, используя информацию на странице и информацию, которая была передана с предыдущих страниц, и, наконец, возвращает элемент.
Если я ограничу это одной категорией инаберите (например, contains[@href, "filter=c:Grinders"]
и contains[@href, "filter=t:Disc+-+Horizontal%2C+Single+End"]
), тогда это сработает, и на последней странице есть элемент машины для каждой машины.Проблема заключается в том, что, как только я позволяю пауку убирать все категории и все типы, он возвращает только те предметы, которые были убраны для машин, на первой из последних страниц, на которые он попадает, и после того, как он сделал это, паук закончил и неполучить другие категории и т. д.
Вот (анонимный) код
from scrapy.selector import HtmlXPathSelector
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.http import Request
from myspider.items import MachineItem
import urlparse
class MachineSpider(CrawlSpider):
name = 'myspider'
allowed_domains = ['example.com']
start_urls = ['http://www.example.com/index.php']
rules = (
Rule(SgmlLinkExtractor(allow_domains=('example.com'),allow=('12\.html'),unique=True),callback='parsecatpage'),
)
def parsecatpage(self, response):
hxs = HtmlXPathSelector(response)
#this works, next line doesn't categories = hxs.select('//a[contains(@href, "filter=c:Grinders")]')
categories = hxs.select('//a[contains(@href, "filter=c:Grinders") or contains(@href, "filter=c:Lathes")]')
for cat in categories:
item = MachineItem()
req = Request(urlparse.urljoin(response.url,''.join(cat.select("@href").extract()).strip()),callback=self.parsetypepage)
req.meta['item'] = item
req.meta['machinecategory'] = ''.join(cat.select("./text()").extract())
yield req
def parsetypepage(self, response):
hxs = HtmlXPathSelector(response)
#this works, next line doesn't types = hxs.select('//a[contains(@href, "filter=t:Disc+-+Horizontal%2C+Single+End")]')
types = hxs.select('//a[contains(@href, "filter=t:Disc+-+Horizontal%2C+Single+End") or contains(@href, "filter=t:Lathe%2C+Production")]')
for typ in types:
item = response.meta['item']
req = Request(urlparse.urljoin(response.url,''.join(typ.select("@href").extract()).strip()),callback=self.parsemachinelist)
req.meta['item'] = item
req.meta['machinecategory'] = ': '.join([response.meta['machinecategory'],''.join(typ.select("./text()").extract())])
yield req
def parsemachinelist(self, response):
hxs = HtmlXPathSelector(response)
for row in hxs.select('//tr[contains(td/a/@href, "action=searchdet")]'):
item = response.meta['item']
req = Request(urlparse.urljoin(response.url,''.join(row.select('./td/a[contains(@href,"action=searchdet")]/@href').extract()).strip()),callback=self.parsemachine)
print urlparse.urljoin(response.url,''.join(row.select('./td/a[contains(@href,"action=searchdet")]/@href').extract()).strip())
req.meta['item'] = item
req.meta['descr'] = row.select('./td/div/text()').extract()
req.meta['machinecategory'] = response.meta['machinecategory']
yield req
def parsemachine(self, response):
hxs = HtmlXPathSelector(response)
item = response.meta['item']
item['machinecategory'] = response.meta['machinecategory']
item['comp_name'] = 'Name'
item['description'] = response.meta['descr']
item['makemodel'] = ' '.join([''.join(hxs.select('//table/tr[contains(td/strong/text(), "Make")]/td/text()').extract()),''.join(hxs.select('//table/tr[contains(td/strong/text(), "Model")]/td/text()').extract())])
item['capacity'] = hxs.select('//tr[contains(td/strong/text(), "Capacity")]/td/text()').extract()
relative_image_url = hxs.select('//img[contains(@src, "custom/modules/images")]/@src')[0].extract()
abs_image_url = urlparse.urljoin(response.url, relative_image_url.strip())
item['image_urls'] = [abs_image_url]
yield item
SPIDER = MachineSpider()
Так, например, паук найдет измельчители на странице категории и перейдет на страницу типа измельчителя, где он будетнайдите тип диска Горизонтальный одинарный конец, затем он перейдет на эту страницу, найдет список машин и перейдет на страницу каждой машины, и, наконец, будет элемент для каждой машины.Если вы попытаетесь перейти к шлифовальным станкам и токарным станкам, хотя он будет нормально проходить через шлифовальные станки, он будет сканировать страницы типа токарных и токарных станков и останавливаться на этом без генерации запросов на страницу со списком токарных станков и последние страницы станков.*Может кто-нибудь помочь с этим?Почему паук не попадает на вторую (или третью и т. Д.) Страницу со списком машин, если существует более одной категории машин?
Извините за эпический пост, просто пытаюсь объяснить проблему !!
Спасибо !!