使用Scrapy连续捕获嵌套页面中的数据

时间:2013-12-09 21:31:48

标签: scrapy meta

我正在尝试使用Scrapy BaseSpider抓取一个相当简单的网站,因为我事先知道我想抓取的所有链接都在哪里。

要抓取的网站的基本布局是

  1. 国家名单
  2. 州内的县名单
  3. 县内代理商名单
  4. 有关单一机构的信息
  5. 我可以成功导航并获取所有4个级别的数据,但是,我的县字段未正确填充。对于一个特定的机构而言,我获得了该机构所在州的最后一个县,而不是它所在的实际县。

    示例:

    • OH - 县#3 - 代理商#1(应该是县#1
    • OH - 县#3 - 代理商#2(应该是县#2
    • OH - 县#3 - 代理商#3(正确)

    似乎无法弄清楚我认为相对简单的事情。

    以下是代码:

    from scrapy.spider import BaseSpider
    from scrapy.selector import Selector
    from agencyspider.items import AgencyItem
    from scrapy.http import Request
    
    class BasicspiderSpider(BaseSpider):
        name = "basicSpider"
        allowed_domains = ["usacops.com"]
        start_urls = [
            'http://www.usacops.com/',
            ]
    
        items = {}
    
        def parse(self, response):
            sel = Selector(response)
            states = sel.xpath('//comment()[.=" Begin State Names "]/following::table[1]/tr/td/a')
            for s in states:
                item = AgencyItem()
                state = s.xpath('text()').extract()[0]
                url = s.xpath('@href').extract()[0]
                item['state'] = state
                item['stateUrl']= url
                yield Request(url=url,callback=self.parse_counties,meta={'item':item})
    
    
        def parse_counties(self, response):
            sel = Selector(response)
            counties = sel.xpath('//comment()[.=" Begin Counties "]/following::table[1]/tr/td/font/a | //comment()[.=" Begin Counties "]/following::table[1]/tr/td/a')
            for c in counties:
                item = response.request.meta["item"]
                county = c.xpath('text()').extract()[0]
                countyUrl = c.xpath('@href').extract()[0]
                url = item["stateUrl"] + countyUrl
                item["county"]=county
                item["countyUrl"]=url
                yield Request(url=url, callback=self.parse_agencies,meta={'item':item})
    
        def parse_agencies(self,response):
            sel = Selector(response)
            agencies = sel.xpath('//table[9]/tr/td/table[2]/tr/td/font/a | //table[9]/tr/td/table[2]/tr/td/a')
            for a in agencies:
                item = response.request.meta["item"]
                agency = a.xpath('text()').extract()[0]
                agencyUrl = a.xpath('@href').extract()[0]
                url =  item["stateUrl"] + agencyUrl
                item["agency"] = agency
                item["agencyUrl"] = url 
                yield Request(url=url, callback=self.parse_agencyinfo,meta={'item':item})
    
        def parse_agencyinfo(self,response):
            sel = Selector(response)        
            item = response.request.meta["item"]
            item["agency"]= ' '.join(sel.xpath('//comment()[.=" Begin center section "]/following::table/tr/td/strong/font[1]/text()').extract())
            item["admintype"]= ' '.join(sel.xpath('//comment()[.=" Begin center section "]/following::table/tr/td/strong/font[2]/text()').extract())
            item["adminhead"]= ' '.join(sel.xpath('//comment()[.=" Begin center section "]/following::table/tr/td/strong/font[3]/text()[1]').extract())
            item["address"]= ' '.join(sel.xpath('//comment()[.=" Begin center section "]/following::table/tr/td/strong/font[3]/text()[position()>1]').extract())
            return item
    

1 个答案:

答案 0 :(得分:3)

嘿所以问题是每次你指定item = response.request.meta["item"]你的引用并一遍又一遍地分配同一个项目。

幸运的是它很容易解决!只需使用response.request.meta["item"]包裹AgencyItem(response.request.meta["item"]),即可为每个县创建一个州{{}}州项目。

另外不要忘记在其他回调中执行相同的操作,否则您将遇到其他字段的问题。希望有所帮助!