php爬取房源,(python) scrapy抓取房天下房源信息
一、前言
研究房價走勢和房源信息。
二、知識準備
1.python相關(guān)知識儲備
2.對Scrapy框架有基本的了解,知道其運行流程和邏輯
3.Xpath和CSS選擇器相關(guān)知識(本文只使用Xpath,要使用CSS選擇器的同學(xué)請自行學(xué)習(xí))
三、開始編碼
1.新建工程
安裝Scrapy過程就略過了,首先在通過命令 scrapy startproject shuofangwang新建工程,使用Pycharm打開可以看到其目錄結(jié)構(gòu)如下
這些文件分別是:
scrapy.cfg: 項目的配置文件
shuofangwan/: 該項目的python模塊。之后您將在此加入代碼。
shuofangwan/items.py: 項目中的item文件.
shuofangwan/pipelines.py: 項目中的pipelines文件.
shuofangwan/settings.py: 項目的設(shè)置文件.
shuofangwan/spiders/: 放置spider代碼的目錄.
2.定義Item
Item 是保存爬取到的數(shù)據(jù)的容器,class HouseItem定義你要保存的數(shù)據(jù)。import scrapy
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
class HouseItem(scrapy.Item):
HouseName = scrapy.Field() #樓盤名
HousePrice = scrapy.Field() #價格
HouseAddress = scrapy.Field() #區(qū)域
HouseDetailAddress = scrapy.Field() #詳細地址
House_type = scrapy.Field() #戶型
HouseComment = scrapy.Field() #留言條數(shù)
3.編寫爬蟲Spider
創(chuàng)建一個Spider,必須繼承 scrapy.Spider 類, 且定義以下三個屬性name: 用于區(qū)別Spider。 該名字必須是唯一的,您不可以為不同的Spider設(shè)定相同的名字。
start_urls: 包含了Spider在啟動時進行爬取的url列表。 因此,第一個被獲取到的頁面將是其中之一。
后續(xù)的URL則從初始的URL獲取到的數(shù)據(jù)中提取。
parse() 是spider的一個方法。 被調(diào)用時,每個初始URL完成下載后生成的 Response
對象將會作為唯一的參數(shù)傳遞給該函數(shù)。 該方法負責解析返回的數(shù)據(jù)(response
data),提取數(shù)據(jù)(生成item)以及生成需要進一步處理的URL的 Request 對象。
如下代碼為我Spider主代碼模塊#!/usr/bin/env python
# coding:utf-8
import scrapy
import HouseItem
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
class shuofangwnagSpider(scrapy.Spider):
name = "shuofangwang"
allowed_domains = ["newhouse.cs.fang.com"]
offset = 1
url = "http://newhouse.cs.fang.com/house/s/b9"
start_urls = [url + str(offset)+'/']
def parse(self, response):
clears = response.xpath("//div[@class='nlc_details']")
for each in clears:
item = HouseItem.HouseItem()
house_address = each.xpath(".//div[@class='address']")
item['HouseDetailAddress'] = house_address.xpath('.//a/@title').extract()
item['HouseAddress'] = house_address.xpath('.//a/span/text()').extract()
housetypelist = each.xpath(".//div[@class='house_type clearfix']")
item['House_type'] = housetypelist.xpath('string(.)').extract()
house_price = each.xpath(".//div[@class='nhouse_price']")
item['HousePrice'] = house_price.xpath('.//span/text()').extract()
houseeach = each.xpath(".//div[@class='nlcd_name']")
item['HouseName'] = houseeach.xpath('.//a/text()').extract()
item['HouseComment'] = each.xpath(".//span[@class='value_num']/text()").extract()
yield item
if self.offset < 31:
self.offset += 1
yield scrapy.Request(self.url + str(self.offset)+'/', callback = self.parse)
4.數(shù)據(jù)處理
編寫ITEM_PIPELINES處理數(shù)據(jù),Scrapy允許數(shù)據(jù)以JSON、JSON lines、CSV、XML四種格式保存,由于需要進行后續(xù)數(shù)據(jù)統(tǒng)計工作所以保存為CSV格式。在pipeline.py中寫入代碼:import json
import csv
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
class ShuofangwangPipeline(object):
def __init__(self):
self.filename = open('items.csv', 'wb')
self.csvwriter = csv.writer(self.filename, delimiter=',')
self.csvwriter.writerow(['樓盤', '價格', '地址'])
def process_item(self, item, spider):
rows = zip(item['HouseName'], item['HousePrice'], item['HouseAddress'])
for row in rows:
self.csvwriter.writerow(row)
return item
def __init__(self):
self.filename = open('houseData.json', 'w')
def process_item(self, item, spider):
text = json.dumps(dict(item), ensure_ascii=False)+",\n"
self.filename.write(text.encode("utf-8").replace("\\t", "").replace("\\n",""))
print text
def close_spider(self,spider):
self.filename.close()
class Pipeline_ToCSV(object):
def __init__(self):
store_file = 'house.csv'
self.file = open(store_file, 'wb')
self.writer = csv.writer(self.file)
self.writer.writerow(("樓盤", "區(qū)域","價格","戶型","評論" , "地址"))
def process_item(self, item, spider):
housename = str(item['HouseName']).replace('u\'', '\'').replace("\\t", "").replace("\\n","").replace("[","").replace("]","")
houseprice = str(item['HousePrice']).replace('u\'', '\'').replace("\\t", "").replace("\\n","").replace("[","").replace("]","")
houseaddress = str(item['HouseAddress']).replace('u\'', '\'').replace("\\t", "").replace("\\n","").replace("[","").replace("]","")
housedetailaddress = str(item['HouseDetailAddress']).replace('u\'', '\'').replace("\\t", "").replace("\\n","").replace("[","").replace("]","")
housetype = str(item['House_type']).replace('u\'', '\'').replace("\\t", "").replace("\\n","").replace("[","").replace("]","")
housecomment = str(item['HouseComment']).replace('u\'', '\'').replace("\\t", "").replace("\\n","").replace("[","").replace("]","")
housename1 = housename.decode("unicode-escape")
houseprice1 = houseprice.decode("unicode-escape")
houseaddress1 = houseaddress.decode("unicode-escape")
housedetailaddress1 = housedetailaddress.decode("unicode-escape")
housetype1 = housetype.decode("unicode-escape")
housecomment1 = housecomment.decode("unicode-escape")
print '1----'+housename1
print '2----'+houseprice1
print '3----'+houseaddress1
print '4----'+housedetailaddress1
print '5----'+housetype1
print '6----'+housecomment1
self.writer.writerow((housename1,houseaddress1, houseprice1, housetype1, housecomment1, housedetailaddress1))
return item
def close_spider(self,spider):
self.file.close()
然后在settings.py中加入如下代碼:ITEM_PIPELINES = {
#'shuofangwang.pipelines.ShuofangwangPipeline': 1,
'shuofangwang.pipelines.Pipeline_ToCSV':2,
}
ShuofangwangPipeline和Pipeline_ToCSV對應(yīng)的是pipelines.py中的兩個類,第一個是存儲為json格式的用于測試使用所以在工程后期對期進行屏蔽處理,第二個是存儲CSV格式的。其名字后面的1和2代表著優(yōu)先級。
代碼中使用三個replace方法是因為取出的數(shù)據(jù)中含有"tn"等,其并不是我們想要的數(shù)據(jù)所以刪除。
并且要 特別注意 的是extract()取出的數(shù)據(jù)是unicode編碼后的數(shù)據(jù),所以后期的處理一定要注意,這里在最后使用.decode("unicode-escape")對數(shù)據(jù)進行轉(zhuǎn)碼。
抓取日志信息和處理后的數(shù)據(jù)如下:
四、總結(jié)
本文使用的知識點并不多,主要就是對scrapy框架的運行過程流程的了解,對數(shù)據(jù)處理時編碼的處理。對我來說由于第一次使用python編碼爬蟲應(yīng)用,最大的難點就是XPATH對數(shù)據(jù)的選取和數(shù)據(jù)存儲時編碼的處理。聽說python3可以忽略編碼的問題,后續(xù)可以進行嘗試。
總結(jié)
以上是生活随笔為你收集整理的php爬取房源,(python) scrapy抓取房天下房源信息的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 主流人工智能平台的设计和思考
- 下一篇: xorm reverse mysql_x