from itemadapter import ItemAdapter
import json
#字典
from demo_58.items import Demo58Item_ershou,Demo58Item_zufang
#redis指纹服务,数据保存,数据对比
from demo_58.ext_mod import Filter
#实例化对象
fu = Filter()
class Demo58Pipeline_zufang:
def __init__(self):
#文件打开
self.file = open('租房信息.json','a')
def process_item(self, item, spider):
# 判断选择目标数据 --》item.py文件的对应类对象
if isinstance(item,Demo58Item_zufang):
data = dict(item)
tit = data['title'] # 将标题处理成密文
# 判断这个tit不存在的时候
if not fu.isismember(tit):
# 不存在就添加
fu.add_data(tit)
self.file.write(json.dumps(data,ensure_ascii=False)+',\n')
return item
def __del__(self):
self.file.close()
保存二手房信息
class Demo58Pipeline_ershoufang:
def __init__(self):
self.file = open('二手房信息.json', 'a')
def process_item(self, item, spider):
if isinstance(item, Demo58Item_ershou):
data = dict(item)
tit = data['title'] # 将标题处理成密文
# 判断这个tit不存在的时候
if not fu.isismember(tit):
# 不存在就添加
fu.add_data(tit)
self.file.write(json.dumps(data, ensure_ascii=False) + ',\n')
return item
def __del__(self):
self.file.close()
ext_mod 用于对接redis数据库,实现指纹对比,保存
import redis # pip install redis
import hashlib
redis_host = '127.0.0.1'
class Filter(object):
'''将目标数据处理成哈希密文 用密文值比对更快'''
def get_md5(self,val):
md5 = hashlib.md5()
# update()接受待加密对象
md5.update(val.encode('utf-8'))
return md5.hexdigest() #取出密文值
'''将密文添加到队列'''
def add_data(self,url):
# Python与redis建立链接
red = redis.Redis(host=redis_host,port=6379,db=1)
reslut = red.sadd('tc58:set_data',self.get_md5(url))
if reslut == 0:
return False
else:
return True
'''判断是否存在在集合中'''
def isismember(self,url):
# Python与redis建立链接
red = redis.Redis(host=redis_host, port=6379, db=1)
# sismember()判断某内容存在
res = red.sismember('tc58:set_data',self.get_md5(url))
return res
import scrapy
from demo_58.items import Demo58Item_zufang,Demo58Item_ershou
1.导入RedisSpider类
from scrapy_redis.spiders import RedisSpider
2,继承类
class SpiderSpider(RedisSpider):
name = 'spider'
# 3.注释域名和起始URL,不做使用
# allowed_domains = ['58.com']
# start_urls = ['http://58.com/']
# 4 设置redis_key
redis_key = 'spider:start_url'
def parse(self, response):
解析,保存为字典
yield 字典
启动
if __name__ == '__main__':
from scrapy import cmdline
cmdline.execute(['scrapy', 'crawl', 'spider'])
随机ua
class UserAgentDownloadMiddleware:
user_agent = [
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:77.0) Gecko/20190101 Firefox/77.0',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36',
'Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16.2'
]
# 方法名是scrapy规定的方法 (协商机制)
# 每个交给下载器的request对象都会经过该方法,并期望返回response
def process_request(self, request, spider):
# 获取随机请求头
u_a = random.choice(self.user_agent)
# 设置请求头
request.headers['User-Agent'] = u_a
随机ip
class RandomProxy:
ip_list = [
'124.116.116.13:4228',
'122.194.194.139:4212',
'36.42.248.45:4215',
'1.83.250.183:4228',
'49.85.43.175:4223',
'121.205.229.70:4231',
]
def process_request(self, request, spider):
proxy = random.choice(self.ip_list)
# 修改请求的元数据字典
# 如果是将IP以列表随机形式构造 需要加上https://,否则报错
request.meta['proxy'] = 'https://' + proxy
# 如果是将IP以字典形式构造
print('IP:', request.meta)
scrapy_redis
分布式爬取数据
分布式处理数据
断点续爬
启动从机#可启动多个,尽量别超过8个,否则电脑容易出问题
爬虫文件上一级目录下
scrapy runspider 爬虫文件.后缀
启动主机
redis-cli
任务发布
@1为spider中redis_key
lpush @1 网址
如错误欢迎指出,本人也小白,希望尽微薄之力让更多人理解
Original: https://blog.csdn.net/qq_64075230/article/details/128201128
Author: 黎明来临
Title: scrapy_redis配置
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/792870/
转载文章受原作者版权保护。转载请注明原作者出处!