在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/人工智能  Python/ scrapy根據(jù)第一層頁面的鏈接爬取第二層后,第一層的內(nèi)容沒有保存

scrapy根據(jù)第一層頁面的鏈接爬取第二層后,第一層的內(nèi)容沒有保存

2016年統(tǒng)計(jì)用區(qū)劃代碼和城鄉(xiāng)劃分代碼

新手開始學(xué)習(xí)scrapy爬蟲,拿國家統(tǒng)計(jì)局的這個(gè)地區(qū)劃分的網(wǎng)頁來練手。
最終目標(biāo)是:把地區(qū)信息按照province->city->country->town的4層存入數(shù)據(jù)庫(網(wǎng)站上5層,但數(shù)據(jù)量太大了,只打算爬4層),在同一張表中,按級別從高到低入庫,自增主鍵,低級的區(qū)域通過parent_id關(guān)聯(lián)上級地區(qū)。


目前打算先把省和市的信息爬出來,也不搞數(shù)據(jù)庫,就以json格式導(dǎo)出就好。
但是一旦從省的頁面獲取到的各省子頁面的url,進(jìn)去爬市的信息,前面的省的信息就不保存了。
scrapy是自己摸索的,可能一開始就把框架理解錯(cuò)了,望大神指出。

import scrapy
from scrapy_test.items import RegionalismItem


class RegionalismSpider(scrapy.Spider):
    name = 'regionalism'

    def parse(self, response):
        pass

    def start_requests(self):
        url = 'http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/index.html'
        yield scrapy.Request(url=url, callback=self.parse_province)

    def parse_province(self, response):
        provinces = response.css('tr.provincetr > td')
        items = []
        for province in provinces:
            item = RegionalismItem()
            item['name'] = province.css('a::text').extract_first().strip()
            item['url'] = response.urljoin(province.xpath('a/@href').extract_first().strip())
            items.append(item)
            yield scrapy.Request(item['url'], callback=self.parse_city)
        yield items

    def parse_city(self, response):
        citys = response.css('tr.citytr > td:nth-child(2)')
        items = []
        for city in citys:
            item = RegionalismItem()
            item['name'] = city.css('a::text').extract_first().strip()
            item['url'] = response.urljoin(city.xpath('a/@href').extract_first().strip())
            # yield scrapy.Request(item['url'], callback=self.parse_country)
            items.append(item)
        yield items

無論yield和return怎么改來改去,要么就是什么都沒有,要么就是只有市的信息,沒有省。
請問錯(cuò)誤在哪里?

回答
編輯回答
懶洋洋

yield scrapy.Request(item['url'], callback=self.parse_city)

yield scrapy.Request(url=url, callback=self.parse_province)
修改成
yield from scrapy.Request(item['url'], callback=self.parse_city)

yield from scrapy.Request(url=url, callback=self.parse_province)

2017年2月19日 00:54
編輯回答
心上人

scrapy聲明字段的時(shí)候是這樣的:

class ScrapyTestItem(scrapy.Item):
    # define the fields for your item here like:
    name = scrapy.Field()

源碼里,field是繼承了dict

class Field(dict):
    """Container of field metadata"""

因此,定義的字段信息是字典dict類型的,而你自定義了一個(gè)列表并yield返回自然就不行了。

回調(diào)函數(shù)有如下定義:

clipboard.png

可以去掉items,直接yield item 。

2018年3月11日 19:30
編輯回答
薔薇花

看了一下代碼,約摸估計(jì)就是Item返回值的問題。
就是

items = []
for ...:
    item = RegionalismItem()
    ...
    items.append(item)
    ...
yield items

這部分。

測試了一下,運(yùn)行中出現(xiàn)這樣的錯(cuò)誤,驗(yàn)證了我的猜想。
ERROR: Spider must return Request, BaseItem, dict or None, got 'list' in <GET http://www.stats.gov.cn/tjsj/...;

簡單地說就是數(shù)據(jù)抓到了,但你返回的形式有問題,不應(yīng)該以list的形式返回。

返回值 items=[item1,item2,item3,...] 是不被scrapy接受的,你如果直接返回item就不會(huì)出這樣的問題。

建議直接改成:

for ...:
    item = RegionalismItem()
    ...
    yield item

我試了一下,修改之后可以正常抓取數(shù)據(jù)并保存為json文件。

2018年7月5日 17:52