新手开始学习scrapy爬虫,拿国家统计局的这个地区划分的网页来练手。
最终目标是:把地区信息按照province->city->country->town的4层存入数据库(网站上5层,但数据量太大了,只打算爬4层),在同一张表中,按级别从高到低入库,自增主键,低级的区域通过parent_id关联上级地区。
目前打算先把省和市的信息爬出来,也不搞数据库,就以json格式导出就好。
但是一旦从省的页面获取到的各省子页面的url,进去爬市的信息,前面的省的信息就不保存了。
scrapy是自己摸索的,可能一开始就把框架理解错了,望大神指出。
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怎么改来改去,要么就是什么都没有,要么就是只有市的信息,没有省。
请问错误在哪里?
看了一下代码,约摸估计就是Item返回值的问题。
就是
这部分。
测试了一下,运行中出现这样的错误,验证了我的猜想。
ERROR: Spider must return Request, BaseItem, dict or None, got 'list' in <GET http://www.stats.gov.cn/tjsj/...;
简单地说就是数据抓到了,但你返回的形式有问题,不应该以list的形式返回。
返回值 items=[item1,item2,item3,...] 是不被scrapy接受的,你如果直接返回item就不会出这样的问题。
建议直接改成:
我试了一下,修改之后可以正常抓取数据并保存为json文件。