scrapy使用多个item
一个spider文件对应多个多个items模型类
自己的第一个问题 yield
xin_spider.py
import scrapy
from scrapy_shiyan.items import ScrapyShiyanItem, ScrapyShiyanItem_2
class XinSpiderSpider(scrapy.Spider):
name = 'xin_spider'
allowed_domains = ['xinfadi.com.cn']
start_urls = ['http://xinfadi.com.cn/']
def parse(self, response):
items = ScrapyShiyanItem()
items['name'] = 'xiaoming'
items['age'] = 20
yield items
items2 = ScrapyShiyanItem_2()
items2['name2'] = 'daming'
items2['age2'] = 25
items['name'] = 'xiaoming22'
items['age'] = 202
yield items
"""
可以在 yield items 后再写,自己认为的 执行到yield items后,
这个函数就结束了,是不对的,可以写多个yield items
输出:
第一个管道类
第一个items模型类的输出:
xiaoming
20
第一个管道类
{'age': 20, 'name': 'xiaoming'}
第一个items模型类的输出:
xiaoming22
202
"""
items.py
import scrapy
class ScrapyShiyanItem(scrapy.Item):
name = scrapy.Field()
age = scrapy.Field()
class ScrapyShiyanItem_2(scrapy.Item):
name2 = scrapy.Field()
age2 = scrapy.Field()
pipelines.py
class ScrapyShiyanPipeline(object):
def process_item(self, item, spider):
print("第一个管道类")
print("第一个items模型类的输出:")
print(item['name'])
print(item['age'])
return item
如上代码中,items.py文件中有两个模型类
那么如何在一个管道文件中使用分别使用这两个模型类呢?
如下代码,就会遇到这个问题:
xin_spider.py
import scrapy
from scrapy_shiyan.items import ScrapyShiyanItem, ScrapyShiyanItem_2
class XinSpiderSpider(scrapy.Spider):
name = 'xin_spider'
allowed_domains = ['xinfadi.com.cn']
start_urls = ['http://xinfadi.com.cn/']
def parse(self, response):
items = ScrapyShiyanItem()
items['name'] = 'xiaoming'
items['age'] = 20
yield items
items2 = ScrapyShiyanItem_2()
items2['name2'] = 'daming'
items2['age2'] = 25
yield items2
items.py 不变同上
pipelines.py
class ScrapyShiyanPipeline(object):
def process_item(self, item, spider):
print("第一个管道类")
print("第一个items模型类的输出:")
print(item['name'])
print(item['age'])
print("第一个管道类")
print("第二个items模型类的输出:")
print(item['name2'])
print(item['age2'])
return item
如果这样运行的话会报错:
报 KeyError: 'name2' 和KeyError: 'name'
因为 yield items 时将 第一个模型类的数据传入 管道文件中
在管道文件中 有提取出模型类中的字段,
当 运行到 print(item['name2'])时,就会报KeyError: 'name2'
因为在ScrapyShiyanItem 第一个模型类中,我们只是定义了,name和age
所以程序没有在模型类中找到 name2,
这就是使用多个模型类时会遇到的问题,
需要在管道文件中加个判断条件,判断 item是来自哪个模型类的,
然后根据不同模型类进行数据提取
如下:
修改管道文件
from scrapy_shiyan.items import ScrapyShiyanItem, ScrapyShiyanItem_2
class ScrapyShiyanPipeline(object):
def process_item(self, item, spider):
if isinstance(item, ScrapyShiyanItem):
print("第一个管道类")
print("第一个items模型类的输出:")
print(item['name'])
print(item['age'])
elif isinstance(item, ScrapyShiyanItem_2):
print("第一个管道类")
print("第二个items模型类的输出:")
print(item['name2'])
print(item['age2'])
return item
输出:
第一个管道类
第一个items模型类的输出:
xiaoming
20
第一个管道类
第二个items模型类的输出:
daming
25
如果有多个管道类呢,呢
from scrapy_shiyan.items import ScrapyShiyanItem, ScrapyShiyanItem_2
class ScrapyShiyanPipeline(object):
def process_item(self, item, spider):
if isinstance(item, ScrapyShiyanItem):
print("第一个管道类")
print("第一个items模型类的输出:")
print(item['name'])
print(item['age'])
elif isinstance(item, ScrapyShiyanItem_2):
print("第一个管道类")
print("第二个items模型类的输出:")
print(item['name2'])
print(item['age2'])
return item
class ScrapyShiyanPipeline_2(object):
def process_item(self, item, spider):
if isinstance(item, ScrapyShiyanItem):
print("第2个管道类")
print("第一个items模型类的输出:")
print(item['name'])
print(item['age'])
elif isinstance(item, ScrapyShiyanItem_2):
print("第2个管道类")
print("第二个items模型类的输出:")
print(item['name2'])
print(item['age2'])
return item
此时就会输出:
第一个管道类
第一个items模型类的输出:
xiaoming
20
第2个管道类
第一个items模型类的输出:
xiaoming
20
第一个管道类
第二个items模型类的输出:
daming
25
第2个管道类
第二个items模型类的输出:
daming
25
这就是每一个管道类都会输出,数据被输出了两遍
一个spider爬虫文件对应多个管道类
可以在spider中加上,如下代码,为spider指定管道类
custom_settings = {
'ITEM_PIPELINES': {'scrapy_shiyan.pipelines.ScrapyShiyanPipeline_2': 400,},
}
如下:
import scrapy
from scrapy_shiyan.items import ScrapyShiyanItem, ScrapyShiyanItem_2
class XinSpiderSpider(scrapy.Spider):
name = 'xin_spider'
allowed_domains = ['xinfadi.com.cn']
start_urls = ['http://xinfadi.com.cn/']
custom_settings = {
'ITEM_PIPELINES': {'scrapy_shiyan.pipelines.ScrapyShiyanPipeline_2': 400,},
}
再次运行就会只使用 ScrapyShiyanPipeline_2 管道类了
输出如下:
第2个管道类
第一个items模型类的输出:
xiaoming
20
第2个管道类
第二个items模型类的输出:
daming
25
这里又出现一个问题:
就是在一个spider文件中,写爬取了3个网站的代码,那么该如何指定这3个网站的数据,
传输到不同的3个管道类中呢?
我想这样的话,可以在items中加入一项数据,用来判断传到管道中的数据来自哪一个网站,
如果是多个spider文件的话如何对应一个管道类
class XinSpiderSpider(scrapy.Spider):
name = 'xin_spider'
allowed_domains = ['xinfadi.com.cn']
start_urls = ['http://xinfadi.com.cn/']
不同的spider文件就会有不同的 name值,如上代码中的name,
用来标识不同的爬虫文件,
可以在一个管道类中,根据name的值来判断,这个数据是来自哪一个爬虫文件的
class ScrapyShiyanPipeline(object):
def process_item(self, item, spider):
if spider.name=='xin_spider':
if isinstance(item, ScrapyShiyanItem):
print(item['spider'])
print("第一个管道类")
print("第一个items模型类的输出:")
print(item['name'])
print(item['age'])
elif isinstance(item, ScrapyShiyanItem_2):
print("第一个管道类")
print("第二个items模型类的输出:")
print(item['name2'])
print(item['age2'])
elif spider.name=='xin_spider_2':
if isinstance(item, ScrapyShiyanItem):
print(item['spider'])
print("第一个管道类")
print("第一个items模型类的输出:")
print(item['name'])
print(item['age'])
elif isinstance(item, ScrapyShiyanItem_2):
print("第一个管道类")
print("第二个items模型类的输出:")
print(item['name2'])
print(item['age2'])
return item
如果是多个spider文件的话如何对应多个管道类
就是在不同的spider文件中,加上
custom_settings = {
'ITEM_PIPELINES': {'scrapy_shiyan.pipelines.ScrapyShiyanPipeline_2': 400,},
}
给不同的spider文件配置不同的管道
多个spider文件同时运行
之前在爬虫项目根目录下写过一个py文件,内容如下:
from scrapy import cmdline
cmdline.execute("scrapy crawl xin_spider --nolog".split())
可以直接点击运行此py文件就可以启动爬虫
如果想运行多个爬虫也可以这样写:如下:
from scrapy import cmdline
cmdline.execute("scrapy crawl xin_spider --nolog".split())
cmdline.execute("scrapy crawl xin_spider_2 --nolog".split())
但是这样写是,先将 xin_spider 爬虫跑完之后,在跑xin_spider_2
所以我们需要一个真正能够同时并行运行多个爬虫文件的方法:
如下,(也是在根目录下新建一个py文件)
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
settings = get_project_settings()
crawler = CrawlerProcess(settings)
crawler.crawl('爬虫名1')
crawler.crawl('爬虫名2')
crawler.start()
Original: https://blog.csdn.net/weixin_44505901/article/details/115931575
Author: 王轩12
Title: scrapy中多个spider文件和多个items.py以及多个管道文件之间的对应
相关阅读
Title: 阿里天池数据分析入门 利用Pandas分析数据
pd.read_csv用法
ccl = pd.read_csv("1_usa_candidate/ccl.txt", sep = '|',names=['CAND_ID','CAND_ELECTION_YR','FEC_ELECTION_YR','CMTE_ID','CMTE_TP','CMTE_DSGN','LINKAGE_ID'])
sep = ‘|’
sep
读取csv文件时指定的分隔符,默认为逗号。注意:”csv文件的分隔符” 和 “我们读取csv文件时指定的分隔符” 一定要一致。本题中提供的数据分隔符是’|’所以按代码设置,names 将每列的名字加上。
names
- 当names没被赋值时,header会变成0,即选取数据文件的第一行作为列名。(从0开始计数)
- *当 names 被赋值,header 没被赋值时,那么header会变成None。如果都赋值,就会实现两个参数的组合功能

pd.merge()函数介绍
ccl =pd.merge(candidates,ccl)

扩展知识看这个:merge函数详解
DataFrame
DataFrame是Python中Pandas库中的一种数据结构,它类似excel,是一种二维表。
直观理解: DataFrame 是带标签的二维数组
pd.DataFrame(data=None, index=None, columns=None)
ccl =pd.DataFrame(ccl, columns=[ 'CMTE_ID','CAND_ID', 'CAND_NAME','CAND_PTY_AFFILIATION'])
这里从ccl数据表中选中其中的四列,index使用默认的。

fillna()函数
#空值处理,统一填充 NOT PROVIDED
c_itcont['STATE'].fillna('NOT PROVIDED',inplace=True)#fillna函数 填充空值
c_itcont['EMPLOYER'].fillna('NOT PROVIDED',inplace=True)
c_itcont['OCCUPATION'].fillna('NOT PROVIDED',inplace=True)
inplace参数的取值:True、False
True:直接修改原对象
False:创建一个副本,修改副本,原对象不变(缺省默认)
Groupby函数
c_itcont.groupby("CAND_PTY_AFFILIATION").sum().sort_values("TRANSACTION_AMT",ascending=False).head(10)
kind = bar
当使用.plot()绘制Pandas DataFrame时,
默认的 .plot()
用直线连接所有数据点并生成线图。
另一方面, .plot(kind='bar')
将 每个_数据点绘制为 _离散条形。为了在x轴上获得正确的格式,必须在绘图后修改刻度标签。
# 各州捐款总人数可视化,取前10个州的数据
st_amt = c_itcont.groupby('STATE').size().sort_values(ascending=False).head(10)
st_amt.plot(kind='bar')

参数 说明
label 用于图例的标签
ax 要在其上进行绘制的matplotlib subplot对象。如果没有设置,则使用当前matplotlib subplot
style 将要传给matplotlib的风格字符串(for example: ‘ko–’)
alpha 图表的填充不透明(0-1)
kind 可以是’line’, ‘bar’, ‘barh’, ‘kde’
logy 在Y轴上使用对数标尺
use_index 将对象的索引用作刻度标签
rot 旋转刻度标签(0-360)
xticks 用作X轴刻度的值
yticks 用作Y轴刻度的值
xlim X轴的界限
ylim Y轴的界限
grid 显示轴网格线
Original: https://blog.csdn.net/MANNYX/article/details/120731139
Author: MANNYX
Title: 阿里天池数据分析入门 利用Pandas分析数据
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/351277/
转载文章受原作者版权保护。转载请注明原作者出处!