Scrapy爬取二手房信息+可視化數據分析

做者:xiaoyu
微信公衆號:Python數據科學
知乎:Python數據分析師正則表達式


本篇介紹一個scrapy的實戰爬蟲項目,並對爬取信息進行簡單的數據分析。目標是北京二手房信息,下面開始分析。json

網頁結構分析

採用安居客網頁信息做爲二手房的信息來源。直接點擊進入二手房信息的頁面。微信

clipboard.png

每頁的住房信息:

clipboard.png

點開連接後的詳細信息:

clipboard.png

博主並無採用分區域進行爬取,博主是直接進行所有爬取,而後循環下一頁完成的。步驟很簡單,以下:數據結構

  1. 先把每一頁的全部二手住房詳細連接爬取到
  2. 請求每個爬取到的詳細連接,解析住房信息
  3. 完成全部解析後,請求下一頁的連接
  4. 返回步驟一循環,直到返回內容爲空

Scrapy代碼實現

數據結構定義

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,這裏只有一個。
  • 因爲ScrapySpider類中默認使用了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住房信息,並返回載有信息的itemide

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

開始進行爬取:

clipboard.png

數據可視化分析

爬取數據後,咱們獲得了一個csv文件,打開顯示以下:

clipboard.png

而後,咱們將使用jupyter notebook進行數據分析,代碼以下:

clipboard.png

簡單分析一下各大區的每平米二手房單價各大區二手房數量,數據僅爲部分,博主沒等數據所有爬取完,僅供參考。固然也可根據實際狀況進行更復雜的數據分析和機器學習進行房價預測。

效果圖以下:

clipboard.png

clipboard.png

總結

本篇只是一個簡單的例子,一個完整的高效的爬蟲還有不少須要完善。

  • 加入代理ip池
  • scrapd的部署分佈式爬蟲
  • 增量式的爬蟲考慮
  • ....

這些將在後續會慢慢進行介紹,完畢。


關注微信公衆號Python數據科學,獲取 120G 人工智能 學習資料。

圖片描述
圖片描述

相關文章
相關標籤/搜索