python3 scrapy_redis 分散式爬取房天下存mongodb
(一)scrapy_redis 簡單介紹
scrapy_redis基於scrapy框架的基礎上集成了redis,通過了redis實現了去重,多臺伺服器進行分散式的爬取資料。
(二)scrapy_redis 簡單配置
(1)settings.py 檔案中加入兩行程式碼:
#啟用Redis排程儲存請求佇列
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
#確保所有的爬蟲通過Redis去重
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
(2)spider檔案中把scrapy.Spider改為RedisSpider; 加入redis_key
以上就是scrapy_redis在scrapy框架中的簡單配置,更多的配置內容,請檢視以往部落格介紹
(三)房天下爬蟲程式碼的編寫
(一)獲取的內容是優選房源
因為這個頁面是下滑重新整理的,並沒有點選下一頁的操作,而是動態JS進行載入的,我們可以使用審查元素中的網路,檢視介面請求資訊
其中的一個連結:
我們可以看到 page=3 只要我們操控這個變數就完全可以了。
但是:當我們開啟上面的連結的時候,出現一堆的亂碼:
(二)我們在parse()方法中使用decode 方法解碼一下,就可以顯示正常了。
def parse(self,response) :
print(response.body.decode('utf-8'))
敲黑板!!!
因為這裡用了分散式,我使用的方法是一臺專門爬url,就是列表頁的url,另外一臺專門進行列表頁url的解析工作。
基於現在的情況,我現在只有一臺電腦,所以我進行了兩個爬蟲進行執行,一個進行url的爬取,一個進行頁面的解析工作。
(1)url爬取:
(2)頁面解析:
(1)爬取url的spider程式碼:
# -*- coding: utf-8 -*-
# @Time : 2018/4/30 14:14
# @Author : 蛇崽
# @Email : [email protected]
# @File : fangtianxia.py(房天下)
import scrapy
import redis
from scrapy_redis.spiders import RedisSpider
from zhilianspider.settings import REDIS_HOST,REDIS_PWD
class FangtianxiaSpider(RedisSpider):
name = 'fangtianxia'
allowed_domains = ['m.fang.com']
"""
44684 p:16 index 3192
"""
# start_urls = ['https://m.fang.com/zf/?purpose=%D7%A1%D5%AC&jhtype=zf&city=%B1%B1%BE%A9&renttype=cz&c=zf&a=ajaxGetList&city=bj&r=0.7782449595236586&page=1']
base_url = 'https://m.fang.com/zf/?purpose=%D7%A1%D5%AC&jhtype=zf&city=%B1%B1%BE%A9&renttype=cz&c=zf&a=ajaxGetList&city=bj&r=0.7782449595236586&page='
# 獲取到redis
pool = redis.ConnectionPool(host=REDIS_HOST, port=6379, db=0, password=REDIS_PWD)
redis = redis.StrictRedis(connection_pool=pool)
for index in range(1,3192):
star_url = base_url+str(index)
redis.lpush('fangtianxia:start_urls',star_url)
redis_key = 'fangtianxia:start_urls'
def parse(self,response):
#print(response.body.decode('utf-8'))
url = response.xpath("//*[@class='tongjihref']/@href").extract()
for v_url in url:
print(v_url)
n_v_url = 'https:'+v_url
print('nvurl ',n_v_url)
self.redis.rpush('fangtianxia:house_urls',n_v_url)
(2)解析頁面的程式碼
# -*- coding: utf-8 -*-
# @Time : 2018/4/30 14:14
# @Author : 蛇崽
# @Email : 643435675@QQ.com
# @File : fangtianxia.py(房天下)
import scrapy
import redis
from scrapy_redis.spiders import RedisSpider
from zhilianspider.items import FanItem
from zhilianspider.settings import REDIS_HOST,REDIS_PWD
class FangtianxiaSpider(RedisSpider):
name = 'fangtianxia_down'
allowed_domains = ['m.fang.com']
redis_key = 'fangtianxia:house_urls'
# start_urls = ['https://m.fang.com/zf/bj/JHAGT_404572021_11444434x1010063105_163711602.html']
def parse(self,response):
item = FanItem()
item["title"] = response.xpath('//*[@class="xqCaption mb8"]/h1/text()')[0].extract()
item["area"] = response.xpath('//*[@class="xqCaption mb8"]/p/a[2]/text()')[0].extract()
item["location"] = response.xpath('//*[@class="xqCaption mb8"]/p/a[3]/text()')[0].extract()
item["housing_estate"] = response.xpath('//*[@class="xqCaption mb8"]/p/a[1]/text()')[0].extract()
item["rent"] = response.xpath('//*[@class="f18 red-df"]/text()')[0].extract()
item["rent_type"] = response.xpath('//*[@class="f12 gray-8"]/text()')[0].extract()
item["floor_area"] = response.xpath('//*[@class="flextable"]/li[3]/p/text()')[0].extract()
item["house_type"] = response.xpath('//*[@class="flextable"]/li[2]/p/text()')[0].extract()
item["floor"] = response.xpath('//*[@class="flextable"]/li[4]/p/text()')[0].extract()
item["orientations"] = response.xpath('//*[@class="flextable"]/li[5]/p/text()')[0].extract()
item["decoration"] = response.xpath('//*[@class="flextable"]/li[6]/p/text()')[0].extract()
item["house_info"] = response.xpath('//*[@class="xqIntro"]/p/text()')[0].extract()
item["house_tags"] = ",".join(response.xpath('//*[@class="stag"]/span/text()').extract())
yield item
(三)items.py程式碼:
class FanItem(scrapy.Item):
# 標題
title = scrapy.Field()
# 區(朝陽)
area = scrapy.Field()
# 區域 (勁鬆)
location = scrapy.Field()
# 小區 (勁鬆五區)
housing_estate = scrapy.Field()
# 租金
rent = scrapy.Field()
# 建築面積
floor_area = scrapy.Field()
# 戶型
house_type = scrapy.Field()
# 樓層
floor = scrapy.Field()
# 朝向
orientations = scrapy.Field()
# 裝修
decoration = scrapy.Field()
# 房源描述
house_info = scrapy.Field()
# 標籤
house_tags = scrapy.Field()
# 租房型別(押一付三etc)
rent_type = scrapy.Field()
(四)資料展示
現在的資料還沒有爬完,到現在redis的詳情url已經是60萬的資料了,怕要是撐爆了。
mongo資料庫裡面的資料是3萬左右:
總結一下:scrapy_redis 中的url爬取,這是用這個框架以來第一次用的這種方式,或許這種方式更支援分散式操作,一個爬url,多個通過url進行頁面的解析操作,比較解析頁面是比較費時的。
其餘程式碼都是跟前面爬取智聯招聘的程式碼都差不多一樣的,這裡就不貼出來了,完整的程式碼我會上傳上來。