做者:xiaoyu
微信公衆號:Python數據科學
知乎:Python數據分析師正則表達式
本篇介紹一個scrapy
的實戰爬蟲項目,並對爬取信息進行簡單的數據分析。目標是北京二手房信息
,下面開始分析。json
採用安居客網頁信息做爲二手房的信息來源。直接點擊進入二手房信息的頁面。微信
博主並無採用分區域進行爬取,博主是直接進行所有爬取,而後循環下一頁完成的。步驟很簡單,以下:數據結構
Scrapy
中的元數據field
實際上是繼承了Python中的字典
數據類型,使用起來很方便,博主直接定義了幾個住房的信息,以下代碼所示。固然還有高級的用法,配合itemloader
加入processor
,這裏只使用簡單的定義便可。機器學習
class AnjukeItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() price = scrapy.Field() mode = scrapy.Field() area = scrapy.Field() floor = scrapy.Field() age = scrapy.Field() location = scrapy.Field() district = scrapy.Field() pass
Scrapy
自帶的爬蟲類Spider
。name
,它貫穿了整個Scrapy
的始終,後面會看到它的做用。start_urls
是初始請求的url的列表,也能夠有多個初始url,這裏只有一個。Scrapy
的Spider
類中默認使用了Request
請求,所以這裏選擇不覆蓋Request
,使用默認請求,且請求中調用parse回調函數。Scrapy
的高級selector
選擇器的xpath
進行解析。parse
函數請求中有兩個yield
,表明生成器。scrapy
yield
返回每一頁的下一頁連接next_pageurl
。yield
返回每一頁全部的住房詳細連接,並再次Request
請求跟進,而後調用下一個回調函數parse_detail
。請求的過程當中若是速度過快,會要求輸入驗證碼
,這裏放慢了請求速度,暫不處理驗證部分(後續慢慢介紹)。分佈式
class AnjukeSpider(scrapy.Spider): name = 'anjuke' # custom_settings = { # 'REDIRECT_ENABLED': False # } start_urls = ['https://beijing.anjuke.com/sale/'] def parse(self, response): # 驗證碼處理部分 pass # next page link next_url = response.xpath( '//*[@id="content"]/div[4]/div[7]/a[7]/@href').extract()[0] print('*********' + str(next_url) + '**********') if next_url: yield scrapy.Request(url=next_url, callback=self.parse) # 爬取每一頁的全部房屋連接 num = len(response.xpath( '//*[@id="houselist-mod-new"]/li').extract()) for i in range(1, num + 1): url = response.xpath( '//*[@id="houselist-mod-new"]/li[{}]/div[2]/div[1]/a/@href' .format(i)).extract()[0] yield scrapy.Request(url, callback=self.parse_detail)
parse_detail
回調函數中使用itemloader
解析items
住房信息,並返回載有信息的item
。ide
def parse_detail(self, response): houseinfo = response.xpath('//*[@class="houseInfo-wrap"]') if houseinfo: l = ItemLoader(AnjukeItem(), houseinfo) l.add_xpath('mode', '//div/div[2]/dl[1]/dd/text()') l.add_xpath('area', '//div/div[2]/dl[2]/dd/text()') l.add_xpath('floor', '//div/div[2]/dl[4]/dd/text()') l.add_xpath('age', '//div/div[1]/dl[3]/dd/text()') l.add_xpath('price', '//div/div[3]/dl[2]/dd/text()') l.add_xpath('location', '//div/div[1]/dl[1]/dd/a/text()') l.add_xpath('district', '//div/div[1]/dl[2]/dd/p/a[1]/text()') yield l.load_item()
因爲爬取後的items
數據很亂,有各類\n,\t
等符號,所以在pipelines
中進行簡單的清理工做,使用正則表達式
實現,代碼以下:函數
import re def list2str(value): new = ''.join(value).strip() return new class AnjukePipeline(object): def process_item(self, item, spider): area = item['area'] price = item['price'] loc = item['location'] district = item['district'] mode = item['mode'] age = item['age'] floor = item['floor'] modes = list2str(mode) item['area'] = int(re.findall(r'\d+', list2str(area))[0]) item['age'] = int(re.findall(r'\d+', list2str(age))[0]) item['floor'] = list2str(floor) item['location'] = list2str(loc) item['district'] = list2str(district) item['price'] = int(re.findall(r'\d+', list2str(price))[0]) item['mode'] = modes.replace('\t', '').replace('\n', '') return item
別忘記在setting
裏面設置pipeline
參數。學習
ITEM_PIPELINES = { 'anjuke.pipelines.AnjukePipeline': 300, }
咱們想要將爬取的數據輸出到一個文件中,csv
或者json
,咱們這裏輸出爲csv格式
的文件。
在Scrapy中只須要一個command
指令便可完成,在項目文件下的命令行輸入:
scrapy crawl anjuke -o items.csv
命令行中的anjuke
就是最開始咱們定義的name
。
開始進行爬取:
爬取數據後,咱們獲得了一個csv
文件,打開顯示以下:
而後,咱們將使用jupyter notebook
進行數據分析,代碼以下:
簡單分析一下各大區的每平米二手房單價
和各大區二手房數量
,數據僅爲部分,博主沒等數據所有爬取完,僅供參考。固然也可根據實際狀況進行更復雜的數據分析和機器學習進行房價預測。
效果圖以下:
本篇只是一個簡單的例子,一個完整的高效的爬蟲還有不少須要完善。
ip池
scrapd
的部署分佈式爬蟲這些將在後續會慢慢進行介紹,完畢。
關注微信公衆號Python數據科學,獲取 120G
人工智能 學習資料。