跟随链接,Scrapy网页爬虫框架
我看了好几遍Scrapy的文档,还是搞不清楚用CrawlSpider规则和在回调方法中自己实现链接提取机制之间的区别。
我准备用后者的方法写一个新的网络爬虫,但这是因为我在之前的项目中用规则的经历不太好。我真的想知道我在做什么,以及为什么要这么做。
有没有人对这个工具熟悉的?
谢谢你的帮助!
2 个回答
1
如果你想要选择性地抓取网页,比如获取“下一页”的链接等,自己写一个爬虫会更好。不过如果是一般的抓取,建议使用crawlspider,并通过规则和process_links函数来过滤掉那些你不想跟踪的链接。
可以看看crawlspider的代码,路径是\scrapy\contrib\spiders\crawl.py
,其实并不是很复杂。
11
CrawlSpider是从BaseSpider这个基础类继承来的。它主要增加了一些规则,用来提取和跟踪链接。如果这些规则对你来说不够灵活,那就可以使用BaseSpider。
class USpider(BaseSpider):
"""my spider. """
start_urls = ['http://www.amazon.com/s/?url=search-alias%3Dapparel&sort=relevance-fs-browse-rank']
allowed_domains = ['amazon.com']
def parse(self, response):
'''Parse main category search page and extract subcategory search link.'''
self.log('Downloaded category search page.', log.DEBUG)
if response.meta['depth'] > 5:
self.log('Categories depth limit reached (recursive links?). Stopping further following.', log.WARNING)
hxs = HtmlXPathSelector(response)
subcategories = hxs.select("//div[@id='refinements']/*[starts-with(.,'Department')]/following-sibling::ul[1]/li/a[span[@class='refinementLink']]/@href").extract()
for subcategory in subcategories:
subcategorySearchLink = urlparse.urljoin(response.url, subcategorySearchLink)
yield Request(subcategorySearchLink, callback = self.parseSubcategory)
def parseSubcategory(self, response):
'''Parse subcategory search page and extract item links.'''
hxs = HtmlXPathSelector(response)
for itemLink in hxs.select('//a[@class="title"]/@href').extract():
itemLink = urlparse.urljoin(response.url, itemLink)
self.log('Requesting item page: ' + itemLink, log.DEBUG)
yield Request(itemLink, callback = self.parseItem)
try:
nextPageLink = hxs.select("//a[@id='pagnNextLink']/@href").extract()[0]
nextPageLink = urlparse.urljoin(response.url, nextPageLink)
self.log('\nGoing to next search page: ' + nextPageLink + '\n', log.DEBUG)
yield Request(nextPageLink, callback = self.parseSubcategory)
except:
self.log('Whole category parsed: ' + categoryPath, log.DEBUG)
def parseItem(self, response):
'''Parse item page and extract product info.'''
hxs = HtmlXPathSelector(response)
item = UItem()
item['brand'] = self.extractText("//div[@class='buying']/span[1]/a[1]", hxs)
item['title'] = self.extractText("//span[@id='btAsinTitle']", hxs)
...
即使BaseSpider的start_urls对你来说也不够灵活,你可以重写start_requests这个方法。