一般而言,存入数据库中的数据都要进行清洗,但是在解析页面中对数据清洗比较麻烦而且杂乱,对于这种情况scrapy中的scrapy.loader可以很好的解决。
以下是一段数据清洗的代码
首先是解析页面:
import scrapy
from scrapy import Request
from scrpy_item.items import CountryItem,CountryItemLoader
class CitySpider(scrapy.Spider):
name = 'city'
allowed_domains = ['example.com']
def __init__(self):
self.urls = ['http://example.webscraping.com/places/default/view/China-47']
def start_requests(self):
for url_str in self.urls:
yield Request(url_str,callback=self.parse,dont_filter=True)
def parse(self, response):
item = CountryItemLoader(item=CountryItem(),response=response)
#添加相应字段的解析规则
item.add_css('title','tr#places_country__row td.w2p_fw::text')
#item.add_xpath
item.add_css('population','tr#places_population__row td.w2p_fw::text')
item.add_css('capital','tr#places_capital__row td.w2p_fw::text')
return item.load_item()
清洗在items中进行
import scrapy
from scrapy import Field
from scrapy.loader import ItemLoader
from scrapy.loader.processors import MapCompose,TakeFirst,Join
def str_convert(value):
return 'country_' + value
def get_nums(value):
return value.replace(',','')
def str_capital(value):
return 'capital_' + value
class CountryItemLoader(ItemLoader):
#定义一个默认的全局默认输出处理器,TakeFirst取出数组中第一个,相当于extract_fitst()
default_output_processor = TakeFirst()
class CountryItem(scrapy.Item):
#定义一个输入处理器,这里将处理映射到函数str_convert,进行数据清洗
title = Field(input_processor = MapCompose(str_convert),)
population = Field(input_processor=MapCompose(get_nums),)
capital = Field(input_processor=MapCompose(str_capital),)
可以再管道中输出看看结果
class ScrpyItemPipeline(object):
def process_item(self, item, spider):
print('item name is ::',item['title'])
print('item content is :',item['population'])
print('item capital is :',item['capital'])
return item
运行结果如下:
管道中的结果
item name is :: country_China
item content is : 1330044000
item capital is : capital_Beijing
代码中返回的结果
{'capital': 'capital_Beijing','population': '1330044000', 'title': 'country_China'}
以上就是对scrapy中数据清洗的过程,对于大量字段的时候运用会比在解析页面清洗时好的多,不会让代码繁杂。