scrapy分布式爬虫
一:Scrapy-Redis分布式爬虫组件
Scrapy是一个框架,他本身是不支持分布式的。如果我们想要做分布式的爬虫,就需要借助一个组件叫做Scrapy-Redis,这个组件正是利用了Redis可以分布式的功能,集成到Scrapy框架中,使得爬虫可以进行分布式。可以充分的利用资源(多个ip、更多带宽、同步爬取)来提高爬虫的爬行效率。
为什么原生的scrapy不可以实现分布式?
- 调度器不可以被分布式集群共享
- 管道不可以被分布式集群共享
scrapy-redis组件作用:
- 可以给原生的scrapy框架提供可以被共享的管道和调度器
二:分布式爬虫的优点
可以充分利用多台机器的带宽
可以充分利用多台机器的ip地址
多台机器做,爬取效率更高
三:分布式爬虫必须要解决的问题
分布式爬虫是好几台机器在同时运行,如何保证不同的机器爬取页面的时候不会出现重复爬取的问题
分布式爬虫在不同的机器上运行,在把数据爬完后如何保证保存在同一个地方
四:Scrapy-Redis架构图
五:redis安装
https://blog.csdn.net/pcn01/article/details/104516047
六:分布式爬虫改造
6.1 scrapy基础爬虫
(crawler) F:\WWWROOT\crawler>scrapy startproject fang
(crawler) F:\WWWROOT\crawler>cd fang
(crawler) F:\WWWROOT\crawler\fang>scrapy genspider sofang "fang.com"
settings配置文件:
ROBOTSTXT_OBEY = False
DOWNLOAD_DELAY = 3
DOWNLOADER_MIDDLEWARES = {
# 'fang.middlewares.FangDownloaderMiddleware': 543,
'fang.middlewares.UserAgentDownloadMiddleware': 543, # 使用自定义的随机请求头中间件
}
ITEM_PIPELINES = {
'fang.pipelines.FangPipeline': 300,
}
LOG_LEVEL = "WARNING"
随机请求头middlewares.py文件:
import random
class UserAgentDownloadMiddleware(object):
# user-agent随机请求头中间件
USER_AGENT = [
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; pl-PL; rv:1.0.1) Gecko/20021111 Chimera/0.6',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134',
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41 Safari/535.1 QQBrowser/6.9.11079.201',
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17 SE 2.X MetaSr 1.0',
]
def process_request(self, request, spider):
user_agent = random.choice(self.USER_AGENT)
request.headers['User-Agent'] = user_agent
设置字段items.py文件
import scrapy
# 此次爬取每个城市的新房与二手房信息
class NewHouseItem(scrapy.Item):
province = scrapy.Field() # 省份
city = scrapy.Field() # 城市
name = scrapy.Field() # 小区的名字
price = scrapy.Field() # 价格
rooms = scrapy.Field() # 几居室
area = scrapy.Field() # 面积
address = scrapy.Field() # 地址
district = scrapy.Field() # 行政区
sale = scrapy.Field() # 是否在售
origin_url = scrapy.Field() # 详情页面url
class ESFHouseItem(scrapy.Item):
province = scrapy.Field() # 省份
city = scrapy.Field() # 城市
name = scrapy.Field() # 小区的名字
price = scrapy.Field() # 价格
rooms = scrapy.Field() # 几居室
area = scrapy.Field() # 面积
address = scrapy.Field() # 地址
origin_url = scrapy.Field() # 详情页面url
floor = scrapy.Field()
toward = scrapy.Field()
year = scrapy.Field()
unit = scrapy.Field()
sofang.py文件内容如下:
import scrapy
import re
from fang.items import NewHouseItem, ESFHouseItem
class SofangSpider(scrapy.Spider):
name = 'sofang'
allowed_domains = ['fang.com']
start_urls = ['https://www.fang.com/SoufunFamily.htm']
def parse(self, response):
trs = response.xpath('//div[@class="outCont"]//tr')
province = None
for tr in trs:
tds = tr.xpath('.//td[not(@class)]')
province_td = tds