创建一个通用的爬行spider

我的问题确实是与上一个问题相同的方法,但是在Scrapy 0.14中。

使用一个Scrapyspider访问多个网站

基本上,我有一个GUI,它接受域,关键字,标签名称等参数,并且我想创建一个通用的爬虫来为那些标签中的关键字搜寻这些域。通过覆盖spider管理器类或动态创建spider,我已经使用较旧的scrapy版本阅读了冲突的内容。首选哪种方法?如何实现和调用正确的解决方案?提前致谢。

这是我想使通用的代码。它还使用BeautifulSoup。我将其配对,因此希望不会删除对理解它至关重要的任何内容。

class MySpider(CrawlSpider):

name = 'MySpider'

allowed_domains = ['somedomain.com', 'sub.somedomain.com']

start_urls = ['http://www.somedomain.com']

rules = (

Rule(SgmlLinkExtractor(allow=('/pages/', ), deny=('', ))),

Rule(SgmlLinkExtractor(allow=('/2012/03/')), callback='parse_item'),

)

def parse_item(self, response):

contentTags = []

soup = BeautifulSoup(response.body)

contentTags = soup.findAll('p', itemprop="myProp")

for contentTag in contentTags:

matchedResult = re.search('Keyword1|Keyword2', contentTag.text)

if matchedResult:

print('URL Found: ' + response.url)

pass

回答:

我使用Scrapy Extensions方法将Spider类扩展到一个名为Masterspider 的类,该类包括一个通用解析器。

下面是我的通用扩展解析器的非常“简短”的版本。请注意,一旦开始使用AJAX处理页面,就需要使用Javascript引擎(例如Selenium或BeautifulSoup)实现渲染器。还有许多其他代码来管理站点之间的差异(基于列标题的报废,处理相对URL和长URL,管理不同类型的数据容器等)。

使用Scrapy扩展方法的麻烦之处在于,如果某些不适合但我从未必须使用的方法,您仍然可以覆盖通用解析器方法。Masterspider类检查是否在特定于站点的spider类下创建了某些方法(例如parser_start,next_url_parser …),以允许进行特殊性管理:发送表单,根据页面中的元素构造next_url请求等。

由于我要抓取截然不同的网站,因此始终需要进行管理。这就是为什么我更愿意为每个抓取的站点保留一个类,以便我可以编写一些特定的方法来处理它(预处理/后处理,除了PipeLines,Request generators …)。

masterspider / sitespider / settings.py

EXTENSIONS = {

'masterspider.masterspider.MasterSpider': 500

}

masterspider / masterspdier / masterspider.py

# -*- coding: utf8 -*-

from scrapy.spider import Spider

from scrapy.selector import Selector

from scrapy.http import Request

from sitespider.items import genspiderItem

class MasterSpider(Spider):

def start_requests(self):

if hasattr(self,'parse_start'): # First page requiring a specific parser

fcallback = self.parse_start

else:

fcallback = self.parse

return [ Request(self.spd['start_url'],

callback=fcallback,

meta={'itemfields': {}}) ]

def parse(self, response):

sel = Selector(response)

lines = sel.xpath(self.spd['xlines'])

# ...

for line in lines:

item = genspiderItem(response.meta['itemfields'])

# ...

# Get request_url of detailed page and scrap basic item info

# ...

yield Request(request_url,

callback=self.parse_item,

meta={'item':item, 'itemfields':response.meta['itemfields']})

for next_url in sel.xpath(self.spd['xnext_url']).extract():

if hasattr(self,'next_url_parser'): # Need to process the next page URL before?

yield self.next_url_parser(next_url, response)

else:

yield Request(

request_url,

callback=self.parse,

meta=response.meta)

def parse_item(self, response):

sel = Selector(response)

item = response.meta['item']

for itemname, xitemname in self.spd['x_ondetailpage'].iteritems():

item[itemname] = "\n".join(sel.xpath(xitemname).extract())

return item

masterspider / sitespider / spiders / somesite_spider.py

# -*- coding: utf8 -*-

from scrapy.spider import Spider

from scrapy.selector import Selector

from scrapy.http import Request

from sitespider.items import genspiderItem

from masterspider.masterspider import MasterSpider

class targetsiteSpider(MasterSpider):

name = "targetsite"

allowed_domains = ["www.targetsite.com"]

spd = {

'start_url' : "http://www.targetsite.com/startpage", # Start page

'xlines' : "//td[something...]",

'xnext_url' : "//a[contains(@href,'something?page=')]/@href", # Next pages

'x_ondetailpage' : {

"itemprop123" : u"id('someid')//text()"

}

}

# def next_url_parser(self, next_url, response): # OPTIONAL next_url regexp pre-processor

# ...

以上是 创建一个通用的爬行spider 的全部内容, 来源链接: utcz.com/qa/418987.html

回到顶部