用python分析上海二手房數據,用幾十行代碼爬取大規模數據!

用python分析上海二手房數據,用幾十行代碼爬取大規模數據!

一、環境搭建

1、安裝python-3.5.2-amd64和pycharm-community-2016.3.2

參考http://jingyan.baidu.com/article/a17d5285ed78e88098c8f222.html?st=2&net_type=&bd_page_type=1&os=0&rst=&word=www.10010

2、配置網頁解析相關庫

以管理員身份運行命令提示符

1)pip3 install beautifulsoup4

2)pip3 install requests

3)pip3 install lxml

二、源代碼

1、導入beautifulsoup和requests庫

# -*- coding: utf-8 -*-from bs4 import BeautifulSoupimport requests

2、寫爬蟲主函數

def spider_1(url): response = requests.get(url) soup = BeautifulSoup(response.text,'lxml') titles = soup.select('dd > p.title > a') # 標題 hrefs = soup.select('dd > p.title > a') # 鏈接 details = soup.select('dd > p.mt12') # 建築信息 courts = soup.select('dd > p:nth-of-type(3) > a') # 小區 adds = soup.select('dd > p:nth-of-type(3) > span') # 地址 areas = soup.select('dd > div.area.alignR > p:nth-of-type(1)') # 面積 prices = soup.select('dd > div.moreInfo > p:nth-of-type(1) > span.price') # 總價 danjias = soup.select('dd > div.moreInfo > p.danjia.alignR.mt5') # 單價 authors = soup.select('dd > p.gray6.mt10 > a') # 發佈者 tags = soup.select('dd > div.mt8.clearfix > div.pt4.floatl') # 標籤 for title, href, detail, court, add, area, price, danjia, author, tag in zip(titles, hrefs, details, courts, adds, areas, prices, danjias, authors, tags): data = { 'title': title.get_text(), 'href': 'http://esf.xian.fang.com' + href.get('href'), 'detail': list(detail.stripped_strings), 'court': court.get_text(), 'add': add.get_text(), 'area': area.get_text(), 'price': price.get_text(), 'danjia': danjia.get_text(), 'author': author.get_text(), 'tag': list(tag.stripped_strings) } print(data)

3、調用spider_1函數爬取指定網頁

spider_1('http://esf.xian.fang.com/')

4、循環翻頁爬取二手房信息

考慮到每頁只顯示30條,總共100頁,寫一個循環調用的語句,把100頁的內容全部爬下來

# 循環,把第2-100頁全部爬下來page = 1while page < 100: url = 'http://esf.xian.fang.com/house/i3'+str(page+1) spider_1(url) page = page + 1 

由於房天下的二手房信息是實時更新的,其默認排序是按照發布時間,因此在爬取過程中,會有重複的數據,如下圖,3000條數據中有523條重複(為避免重複可以嘗試倒序循環爬取)。

1.1 爬取目的

一個朋友在學習自考,作業是爬取數據進行數據分析,正好最近我在學習python,所以他委託我幫他完成這一工作

1.2使用模塊

requests進行網絡請求、bs4進行數據解析、xlwt進行excel表格存儲

用python分析上海二手房數據,用幾十行代碼爬取大規模數據!

2、網頁結構分析

2.1 首頁分析,獲取數據

用python分析上海二手房數據,用幾十行代碼爬取大規模數據!

網頁鏈接:http://sh.lianjia.com/ershoufang/pudongxinqu 紅色文字對應的是區名

[python] view plain copy

  1. # 指定爬蟲所需的上海各個區域名稱

  2. citys = ['pudongxinqu','minhang','baoshan','xuhui','putuo','yangpu','changning','songjiang',

  3. 'jiading','huangpu','jinan','zhabei','hongkou','qingpu','fengxian','jinshan','chongming','shanghaizhoubian']

[python] view plain copy

  1. def getHtml(city):

  2. url = 'http://sh.lianjia.com/ershoufang/%s/' % city

  3. headers = {

  4. 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'

  5. }

  6. request = requests.get(url=url,headers=headers)

  7. # 獲取源碼內容比request.text好,對編碼方式優化好

  8. respons = request.content

  9. # 使用bs4模塊,對響應的鏈接源代碼進行html解析,後面是python內嵌的解釋器,也可以安裝使用lxml解析器

  10. soup = BeautifulSoup(respons,'html.parser')

  11. # 獲取類名為c-pagination的div標籤,是一個列表

  12. page = soup.select('div .c-pagination')[0]

  13. # 如果標籤a標籤數大於1,說明多頁,取出最後的一個頁碼,也就是總頁數

  14. if len(page.select('a')) > 1:

  15. alist = int(page.select('a')[-2].text)

  16. else:#否則直接取出總頁數

  17. alist = int(page.select('span')[0].text)

  18. saveData(city,url,alist+1)

用python分析上海二手房數據,用幾十行代碼爬取大規模數據!

2.2 獲取每個區的總頁數

用python分析上海二手房數據,用幾十行代碼爬取大規模數據!

2.3 選中一頁查看頁面鏈接規律

用python分析上海二手房數據,用幾十行代碼爬取大規模數據!

具體鏈接地址:http://sh.lianjia.com/ershoufang/pudongxinqu/d2

請求頁面具體數據,數據結構

用python分析上海二手房數據,用幾十行代碼爬取大規模數據!

3.總代碼

我用的是python2.7進行爬取的,不確定在python3之後的運行有沒有問題,建議python2版本進行嘗試

[python] view plain copy

  1. #_*_coding:utf-8_*_

  2. # 導入開發模塊

  3. import requests

  4. # 用於解析html數據的框架

  5. from bs4 import BeautifulSoup

  6. # 用於操作excel的框架

  7. import xlwt

  8. # 創建一個工作

  9. book = xlwt.Workbook()

  10. # 向表格中增加一個sheet表,sheet1為表格名稱 允許單元格覆蓋

  11. sheet = book.add_sheet('sheet1', cell_overwrite_ok=True)

  12. # 指定爬蟲所需的上海各個區域名稱

  13. citys = ['pudongxinqu','minhang','baoshan','xuhui','putuo','yangpu','changning','songjiang',

  14. 'jiading','huangpu','jinan','zhabei','hongkou','qingpu','fengxian','jinshan','chongming','shanghaizhoubian']

  15. def getHtml(city):

  16. url = 'http://sh.lianjia.com/ershoufang/%s/' % city

  17. headers = {

  18. 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'

  19. }

  20. request = requests.get(url=url,headers=headers)

  21. # 獲取源碼內容比request.text好,對編碼方式優化好

  22. respons = request.content

  23. # 使用bs4模塊,對響應的鏈接源代碼進行html解析,後面是python內嵌的解釋器,也可以安裝使用lxml解析器

  24. soup = BeautifulSoup(respons,'html.parser')

  25. # 獲取類名為c-pagination的div標籤,是一個列表

  26. page = soup.select('div .c-pagination')[0]

  27. # 如果標籤a標籤數大於1,說明多頁,取出最後的一個頁碼,也就是總頁數

  28. if len(page.select('a')) > 1:

  29. alist = int(page.select('a')[-2].text)

  30. else:#否則直接取出總頁數

  31. alist = int(page.select('span')[0].text)

  32. # 調用方法解析每頁數據

  33. saveData(city,url,alist+1)

  34. # for i in range(1,alist + 1):

  35. # urlStr = '%sd%s' % (url,i)

  36. # 調用方法解析每頁數據,並且保存到表格中

  37. def saveData(city,url,page):

  38. headers = {

  39. 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'

  40. }

  41. for i in range(1,page):

  42. html = requests.get(url='%sd%s' % (url,i),headers=headers).content

  43. soup = BeautifulSoup(html,'html.parser')

  44. infos = soup.select('.js_fang_list')[0].select('li')

  45. for info in infos:

  46. # print '*'*50

  47. des = info.find('a',class_="text link-hover-green js_triggerGray js_fanglist_title").text

  48. dd = info.find('div',class_='info-table')

  49. nameInfo = dd.find('a',class_='laisuzhou')

  50. name = nameInfo.text # 每套二手房的小區名稱

  51. fangL = dd.find('span').contents[-1].strip().split('|')

  52. room_type = fangL[0].strip() # 每套二手房的戶型

  53. size = fangL[1].strip() # 每套二手房的面積

  54. if len(fangL[2].split('/')) == 2:

  55. region = fangL[2].split('/')[0].strip() # 每套二手房所屬的區域

  56. loucheng = fangL[2].split('/')[1].strip() # 每套二手房所在的樓層

  57. else:

  58. region = ''# 每套二手房所屬的區域

  59. loucheng = fangL[2].strip() # 每套二手房所在的樓層

  60. if len(fangL) != 4:

  61. chaoxiang = '*'

  62. else:

  63. chaoxiang = fangL[3].strip() # 每套二手房的朝向

  64. timeStr = info.find('span',class_='info-col row2-text').contents[-1].strip().lstrip('|')

  65. builtdate = timeStr # 每套二手房的建築時間

  66. # 每套二手房的總價

  67. price = info.find('span',class_='total-price strong-num').text.strip()+u'萬'

  68. # 每套二手房的平方米售價

  69. jun = info.find('span',class_='info-col price-item minor').text

  70. price_union = jun.strip()

  71. # 一定要聲明使用全局的row變量,否則會報錯,說定義前使用了該變量

  72. global row

  73. # 把數據寫入表中,row:行數 第二個參數:第幾列 第三個參數:寫入的內容

  74. sheet.write(row,0,des)

  75. sheet.write(row,1,name)

  76. sheet.write(row,2,room_type)

  77. sheet.write(row,3,size)

  78. sheet.write(row,4,region)

  79. sheet.write(row,5,loucheng)

  80. sheet.write(row,6,chaoxiang)

  81. sheet.write(row,7,price)

  82. sheet.write(row,8,price_union)

  83. sheet.write(row,9,builtdate)

  84. # 每次寫完一行,把行索引進行加一

  85. row += 1

  86. # with open('%s.csv' % city,'ab') as fd:

  87. # allStr = ','.join([name,room_type,size,region,loucheng,chaoxiang,price,price_union,builtdate])+'\n'

  88. # fd.write(allStr.encode('utf-8'))

  89. # 判斷當前運行的腳本是否是該腳本,如果是則執行

  90. # 如果有文件xxx繼承該文件或導入該文件,那麼運行xxx腳本的時候,這段代碼將不會執行

  91. if __name__ == '__main__':

  92. # getHtml('jinshan')

  93. row=0

  94. for i in citys:

  95. getHtml(i)

  96. # 最後執行完了保存表格,參數為要保存的路徑和文件名,如果不寫路徑則默然當前路徑

  97. book.save('lianjia-shanghai.xls')

用python分析上海二手房數據,用幾十行代碼爬取大規模數據!

好了,今天的知識就分享到這裡,歡迎關注愛編程的南風,私信關鍵詞:學習資料,獲取更多學習資源,如果文章對你有有幫助,請收藏關注,在今後與你分享更多學習python的文章。同時歡迎在下面評論區留言如何學習python。


分享到:


相關文章: