items的基本使用方式:
在不同的解析函数之间传递item数据:
阳光热线问政平台案例
"""items"""
import scrapy
class YangguangItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
href = scrapy.Field()
publish_data = scrapy.Field()
content = scrapy.Field()
img = scrapy.Field()
# pass
"""spiders"""
import scrapy
from yangguang.items import YangguangItem # 导入items
class YgSpider(scrapy.Spider):
name = 'yg'
allowed_domains = ['sun0769.com']
start_urls = ['http://wz.sun0769.com/index.php/question/report?'] # start_urls不会经过allowed_domains过滤
def parse(self, response):
tr_list = response.xpath("//div[@class='greyframe']/table[2]/tr/td/table/tr") # elements里的tbody标签 在网页源码中没有
# print(tr_list)
for tr in tr_list:
item = YangguangItem()
item["href"] = tr.xpath(".//td[2]/a[@class='news14']/@href").extract_first()
item["publish_data"] = tr.xpath(".//td[@class='t12wh']/text()").extract_first()
item["title"] = tr.xpath(".//td[2]/a[@class='news14']/@title").extract_first()
yield scrapy.Request( # scrapy.Request构造一个requests 同时指定提取数据的callback函数
item["href"], # 详情页url地址
callback=self.parse_detail, # 详情页处理方式不一样 回调函数调用parse_detail处理
meta={"item": item} # "item"只是一个键可以随便定义 item想要传的数据
# 这里需要用 meta传数据 是因为这一页的内容还没采集完 还有详情页数据没采集
)
# 获取下一页 url 并请求数据 获取响应 提取数据
next_page_url = response.xpath("//div[@class='pagination']/a[text()='>']/@href").extract_first()
print("*" * 100)
print(next_page_url)
if next_page_url is not None:
yield scrapy.Request(
next_page_url,
callback=self.parse # 下一页处理方式一样 回调函数调用自己
# 这里不需要写meta传数据 因为要进入全新的下一页
)
# 处理详情页
def parse_detail(self, response):
item = response.meta["item"] # 取出"item"的值
# 抓取到的文字有很多"'\xa0\xa0' " 在管道中处理
item["content"] = response.xpath("//div[@class='wzy1']//tr[1]/td[@class='txt16_3']//text()").extract()
item["img"] = response.xpath("//div[@class='wzy1']//td[@class='txt16_3']//img/@src").extract()
item["img"] = ["http://wz.sun0769.com" + i for i in item["img"]]
yield item # 把数据传给pipelines
"""pipelines"""
import re
class YangguangPipeline(object):
def process_item(self, item, spider):
item["content"] = self.process_content(item["content"]) # 这里调用process_content() 并传参
return item
def process_content(self, content): # 处理content中的多余字符
content = [re.sub(r"\xa0|\s", "", i) for i in content] # 去除\xa0和空格 替换为空字符串
content = [i for i in content if len(i) > 0] # 去除空字符串
return content