カテゴリページ>タイプページ>リストページ>アイテムページのような構造を持つサイトをクロールするために、scrapy crawlspiderを作成しました。カテゴリページには、それぞれにタイプの多いタイプページがあり、それぞれのタイプにはアイテムのリストがあり、最後に各マシンには情報に関するページがあります。Scrapy:ネストされたコールバック内のすべてのリンクを生成しないクロールスプレッド
私のスパイダーは、ホームページからコールバックparsecatpageを定義するカテゴリページに到達するルールを持っています。これはアイテムを生成し、カテゴリを取得してページの各カテゴリに対して新しいリクエストを生成します。私はitem.metaで項目とカテゴリ名を渡し、コールバックはparsetypeページを指定します。
Parsetypepageはresponse.metaからアイテムを取得し、各タイプのリクエストを生成し、item.metaにアイテムとカテゴリおよびタイプの連結を渡します。コールバックはparsemachinelistです。
Parsemachinelistはresponse.metaからアイテムを取得し、リスト上の各アイテムの要求を生成し、item.category.metaを介してitem、category/type、descriptionを最終コールバックparsemachineに渡します。これにより、メタ属性が取得され、ページ内の情報と前のページから渡された情報が使用され、アイテム内のすべてのフィールドに入力され、最後にアイテムが生成されます。
これを1つのカテゴリとタイプ(たとえば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()
したがって、たとえばクモは、カテゴリページのグラインダを見つけるとグラインダー型のページに移動している他のカテゴリなどを取得シングルエンドタイプであれば、そのページに行き、マシンのリストを見つけて各マシンページに行き、最後に各マシンのためのアイテムがあります。グラインダと旋盤を試してみると、それはグラインダをうまく通り抜けますが、旋盤と旋盤のタイプのページがクロールされ、旋盤リストページと最終旋盤ページのリクエストが生成されません。
誰でも助けてもらえますか?複数のカテゴリのマシンがあると、スパイダーが2番目(または3番目など)のマシンリストページに移動しないのはなぜですか?
叙事詩のポストに申し訳ありません、問題を説明しようとしています!
ありがとうございます!
このサイトで有用な回答/質問が見つかった場合は、それらをupvoteしてください – warvariuc