python3 爬蟲教學之爬取鏈家二手房(最下面源碼) //以更新源碼


前言

作為一只小白,剛進入Python爬蟲領域,今天嘗試一下爬取鏈家的二手房,之前已經爬取了房天下的了,看看鏈家有什么不同,馬上開始。

一、分析觀察爬取網站結構

這里以廣州鏈家二手房為例:http://gz.lianjia.com/ershoufang/

這是第一頁,我們看看第二頁的url會有什么變化發現多出來一個/g2,第三頁/pg3,那么原始的是不是就是增加/pg1呢,我們測試一下http://gz.lianjia.com/ershoufang/pg1/  ==  http://gz.lianjia.com/ershoufang/那么問題不大,我們繼續分析。

 

這些就是我們想得到的二手房資訊,但是這個是有鏈接可以點進去的,我們看看:

里面的二手房資訊更加全面,那我是想得到這個網頁里面的資訊了。

二、編寫爬蟲

1.得到url

  我們先可以得到全部詳細的鏈接,這里有100頁,那么我們可以http://gz.lianjia.com/ershoufang/pg1/.../pg2.../pg3.../pg100    先生成全部url,再從這些url得到每一頁里面詳細的url,再從詳細的url分析html得到我想要的資訊。

 

2.分析  htmlhttp://gz.lianjia.com/ershoufang/pg1/

  先打開chrom自帶的開發者工具分析里面的network,把preserve log勾上,清空,然后我們刷新一下網頁。

發現get:http://gz.lianjia.com/ershoufang/pg1/請求到的html

那么我們就可以開始生成全部url先了:

def generate_allurl(user_in_nub):
    url = 'http://gz.lianjia.com/ershoufang/pg{}/'
    for url_next in range(1,int(user_in_nub)):
        yield url.format(url_next)

def main():
    user_in_nub = input('輸入生成頁數:')
    for i in generate_allurl(user_in_nub):
        print(i)

if __name__ == '__main__':
    main()

  運行結果:

 

 這樣我們就生成了100頁的url

 

然后我們就要分析這些url里面的詳細每一頁的url:

  先分析網頁結構,

  發現我們要的url是再class為title里面的a標簽,我們可以使用request來獲取html,用正則表達法來分析獲取詳情頁url:

import requests
import re

  def一個方法,把得到的generate_allurl傳進來再打印一下看看

def get_allurl(generate_allurl):
    get_url = requests.get(generate_allurl,)
    if get_url.status_code == 200:
        re_set = re.compile('<li.*?class="clear">.*?<a.*?class="img.*?".*?href="(.*?)"')
        re_get = re.findall(re_set,get_url.text)
        print(re_get)

  

      正常獲取詳細頁的鏈接

下一步我們就要分析這些詳細頁連接以獲取里面的資訊,使用自帶開發者工具點擊這個箭頭可以選擇網頁元素:

  

    發現資訊在一個class為main里面,可以用BeautifulSoup模塊里面的方法得到:

from bs4 import BeautifulSoup

  定義一個方法來把詳情url鏈接傳進來分析:

def open_url(re_get):
    res = requests.get(re_get)
    if res.status_code == 200:
        info = {}
        soup = BeautifulSoup(res.text,'lxml')
        info['標題'] = soup.select('.main')[0].text
        info['總價'] = soup.select('.total')[0].text + '萬'
        info['每平方售價'] = soup.select('.unitPriceValue')[0].text
        return info

  這里把requests.get對象傳給res,然后把這個變量傳給BeautifulSoup,用lxml解析器解析,再把結果傳給soup,然后就可以soup.select方法來篩選,因為上面標題在,main下:

      soup.select('.main'),因為這里是一個class,所以前面要加.,如果篩選的是id,則加#。

得到如下結果:

是一個list,所以我們要加[ 0 ]取出,然后可以運用方法 .text得到文本。

def open_url(re_get):
res = requests.get(re_get)
if res.status_code == 200:
soup = BeautifulSoup(res.text,'lxml')
title = soup.select('.main')[0].text
print(title)

      得到結果

      然后還可以添加到字典,return返回字典:

def open_url(re_get):
    res = requests.get(re_get)
    if res.status_code == 200:
        info = {}
        soup = BeautifulSoup(res.text,'lxml')
        info['標題'] = soup.select('.main')[0].text
        info['總價'] = soup.select('.total')[0].text + '萬'
        info['每平方售價'] = soup.select('.unitPriceValue')[0].text
        return info

        得到結果:

        還可以儲存到xlsx文檔里面:

def pandas_to_xlsx(info):
    pd_look = pd.DataFrame(info)
    pd_look.to_excel('鏈家二手房.xlsx',sheet_name='鏈家二手房')

        

      ok基本完成,可能有沒有說清楚的,留言我繼續更新

 

 1 #!/usr/bin/env python3
 2 # -*- coding: utf-8 -*-
 3 # Author;Tsukasa
 4 
 5 import json
 6 from multiprocessing import Pool
 7 import requests
 8 from bs4 import BeautifulSoup
 9 import re
10 import pandas as pd
11 import pymongo
12 
13 
14 def generate_allurl(user_in_nub, user_in_city):  # 生成url
15     url = 'http://' + user_in_city + '.lianjia.com/ershoufang/pg{}/'
16     for url_next in range(1, int(user_in_nub)):
17         yield url.format(url_next)
18 
19 
20 def get_allurl(generate_allurl):  # 分析url解析出每一頁的詳細url
21     get_url = requests.get(generate_allurl, 'lxml')
22     if get_url.status_code == 200:
23         re_set = re.compile('<li.*?class="clear">.*?<a.*?class="img.*?".*?href="(.*?)"')
24         re_get = re.findall(re_set, get_url.text)
25         return re_get
26 
27 
28 def open_url(re_get):  # 分析詳細url獲取所需信息
29     res = requests.get(re_get)
30     if res.status_code == 200:
31         info = {}
32         soup = BeautifulSoup(res.text, 'lxml')
33         info['標題'] = soup.select('.main')[0].text
34         info['總價'] = soup.select('.total')[0].text + ''
35         info['每平方售價'] = soup.select('.unitPriceValue')[0].text
36         info['參考總價'] = soup.select('.taxtext')[0].text
37         info['建造時間'] = soup.select('.subInfo')[2].text
38         info['小區名稱'] = soup.select('.info')[0].text
39         info['所在區域'] = soup.select('.info a')[0].text + ':' + soup.select('.info a')[1].text
40         info['鏈家編號'] = str(re_get)[33:].rsplit('.html')[0]
41         for i in soup.select('.base li'):
42             i = str(i)
43             if '</span>' in i or len(i) > 0:
44                 key, value = (i.split('</span>'))
45                 info[key[24:]] = value.rsplit('</li>')[0]
46         for i in soup.select('.transaction li'):
47             i = str(i)
48             if '</span>' in i and len(i) > 0 and '抵押信息' not in i:
49                 key, value = (i.split('</span>'))
50                 info[key[24:]] = value.rsplit('</li>')[0]
51         print(info)
52         return info
53 
54 
55 def update_to_MongoDB(one_page):  # update儲存到MongoDB
56     if db[Mongo_TABLE].update({'鏈家編號': one_page['鏈家編號']}, {'$set': one_page}, True): #去重復
57         print('儲存MongoDB 成功!')
58         return True
59     return False
60 
61 
62 def pandas_to_xlsx(info):  # 儲存到xlsx
63     pd_look = pd.DataFrame(info)
64     pd_look.to_excel('鏈家二手房.xlsx', sheet_name='鏈家二手房')
65 
66 
67 def writer_to_text(list):  # 儲存到text
68     with open('鏈家二手房.text', 'a', encoding='utf-8')as f:
69         f.write(json.dumps(list, ensure_ascii=False) + '\n')
70         f.close()
71 
72 
73 def main(url):
74 
75     writer_to_text(open_url(url))    #儲存到text文件
76     # update_to_MongoDB(list)   #儲存到Mongodb
77 
78 
79 if __name__ == '__main__':
80     user_in_city = input('輸入爬取城市:')
81     user_in_nub = input('輸入爬取頁數:')
82 
83     Mongo_Url = 'localhost'
84     Mongo_DB = 'Lianjia'
85     Mongo_TABLE = 'Lianjia' + '\n' + str('zs')
86     client = pymongo.MongoClient(Mongo_Url)
87     db = client[Mongo_DB]
88     pool = Pool()
89     for i in generate_allurl('2', 'zs'):
90         pool.map(main, [url for url in get_allurl(i)])

 

源碼地址:https://gist.github.com/Tsukasa007/660fce644b7dd33afc57998fdc6c376a


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM