第一周/實戰作業: 抓取房屋信息

1. 引言

進入58房屋出租頁面, 爬取列表頁中除了推廣房屋外的正常房屋信息

Paste_Image.png
Paste_Image.png

網址: http://sh.58.com/zufang/0/j2/pn1/

2. 分析

  • 推廣房屋信息的鏈接中有關鍵字'short', 過慮掉
  • 瀏覽量信息要通過JS請求才能獲取
Paste_Image.png

3. 實現部分

# vim spider_zufang.py

代碼

#!/usr/bin/env python3                                                                                                                                                                                             
# -*- coding: utf-8 -*-                                                                                                                                                                                            
                                                                                                                                                                                                                   
__author__ = 'jhw'                                                                                                                                                                                                 
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
from bs4 import BeautifulSoup                                                                                                                                                                                      
import requests                                                                                                                                                                                                    
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
# 定義獲取瀏覽量函數                                                                                                                                                                                               
def get_view(url):                                                                                                                                                                                                 
                                                                                                                                                                                                                   
    # 截取鏈接中的ID                                                                                                                                                                                               
    id = url.split('/')[-1].strip('x.shtml')                                                                                                                                                                       
    # 請求瀏覽量的URL可以按F12, 然后在Sources下的'jst1.58.com'中可以看到                                                                                                                                           
    api = 'http://jst1.58.com/counter?infoid={}'.format(id)                                                                                                                                                        
    # 模擬瀏覽器請求瀏覽數                                                                                                                                                                                         
    headers = {                                                                                                                                                                                                    
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36',                                                                                 
        'Accept': '*/*',                                                                                                                                                                                           
        'Accept-Encoding': 'gzip, deflate, sdch',                                                                                                                                                                  
        'Accept-Language': 'zh-CN,zh;q=0.8',                                                                                                                                                                       
        'Cache-Control': 'max-age=0',                                                                                                                                                                              
        'Connection': 'keep-alive',                                                                                                                                                                                
        'Host': 'jst1.58.com',                                                                                                                                                                                     
        # 將ID放入引用中                                                                                                                                                                                           
        'Referer': 'http://sh.58.com/zufang/{}x.shtml'.format(id)                                                                                                                                                  
    }                                                                                                                                                                                                              
    # 返回數據中的最后一串數字即為瀏覽量                                                                                                                                                                           
    view = requests.get(api, headers=headers).text.split('=')[-1]                                                                                                                                                  
                                                                                                                                                                                                                   
    return view                                                                                                                                                                                                    
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
# 定義獲取房屋鏈接函數, 'room_num'為戶型, 可選擇的戶型有'j1 j2 j3 j4'(j1為一室)或者不選                                                                                                                            
def get_url_from(room_num='', who_sells=0):                                                                                                                                                                        
                                                                                                                                                                                                                   
    url_list = []                                                                                                                                                                                                  
    # 此處定義要獲取多少頁的房屋鏈接                                                                                                                                                                               
    urls = ['http://sh.58.com/zufang/{}/{}/pn{}/'.format(str(who_sells), room_num, page) for page in range(1, 5)]                                                                                                  
    for url in urls:                                                                                                                                                                                               
        print(url)                                                                                                                                                                                                 
        data = requests.get(url)                                                                                                                                                                                   
        soup = BeautifulSoup(data.text, 'lxml')                                                                                                                                                                    
        links = soup.select('td.t.qj-rentd > a.t')                                                                                                                                                                 
        for link in links:                                                                                                                                                                                         
            # 鏈接'?'后信息無用, 過慮掉                                                                                                                                                                            
            link_url = link.get('href').split('?')[0]                                                                                                                                                              
            # 過慮推廣鏈接                                                                                                                                                                                         
            if 'short' in link_url:                                                                                                                                                                                
                # print('Advertising infomation...')                                                                                                                                                               
                pass                                                                                                                                                                                               
            else:                                                                                                                                                                                                  
                url_list.append(link_url)                                                                                                                                                                          
    return url_list
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
# 定義獲取房屋信息函數                                                                                                                                                                                             
def get_item_info(url):                                                                                                                                                                                            
                                                                                                                                                                                                                   
    data = requests.get(url)                                                                                                                                                                                       
    soup = BeautifulSoup(data.text, 'lxml')                                                                                                                                                                        
    titles = soup.select('.house-title h1')                                                                                                                                                                        
    updates = soup.select('.title-right-info span')                                                                                                                                                                
    prices = soup.select('.ncolor em')                                                                                                                                                                             
    types = soup.select('.fl.house-type')                                                                                                                                                                          
    areas = soup.select('.fl.xiaoqu > a')                                                                                                                                                                          
    addrs = soup.select('div.house-primary-content-wrap.fr > ul > li:nth-of-type(4) > div')                                                                                                                        
    addr = addrs[0].get_text().strip() if addrs else '火星'                                                                                                                                                        
                                                                                                                                                                                                                   
    data = {                                                                                                                                                                                                       
        'title': titles[0].get_text(),                                                                                                                                                                             
        'update': updates[0].get_text().split(':')[-1],                                                                                                                                                           
        'view': get_view(url),                                                                                                                                                                                     
        'price': prices[0].get_text(),                                                                                                                                                                             
        'type': (types[0].get_text().strip().replace('\t', '').replace('\r\n', '').replace(' ', '').replace('\xa0', '')) if types else None,                                                                       
        'area': [i.get_text() for i in areas if areas],                                                                                                                                                            
        'addr': addr if len(addr) <= 20 else '火星',                                                                                                                                                               
        'url': url,                                                                                                                                                                                                
    }                                                                                                                                                                                                              
    print(data)                                                                                                                                                                                                    
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
# 得到一個3室房屋的列表                                                                                                                                                                                            
url_list = get_url_from('j3')                                                                                                                                                                                      
# 輸出房屋信息                                                                                                                                                                                                     
for url in url_list:                                                                                                                                                                                               
    get_item_info(url)
# python3 spider_zufang.py

結果

{'title': '青浦華新鎮夢里水鄉 3室2廳 139平米 精裝修 押一付三(個人)', 'price': '4000', 'url': 'http://sh.58.com/zufang/26540912168876x.shtml', 'addr': '新風中路358弄', 'view': '84', 'area': ['青浦', '華新鎮'], 'type': '3室2廳2衛-139m2-低層(共6層)精裝修-朝向南北-公寓', 'update': '2016-07-05'}
{'title': '青浦華新鎮星尚灣 3室2廳 137平米 毛坯 押一付三(個人)', 'price': '2600', 'url': 'http://sh.58.com/zufang/26542009472690x.shtml', 'addr': '新鳳中路', 'view': '226', 'area': ['青浦', '華新鎮'], 'type': '3室2廳2衛-137m2-中層(共18層)毛坯-朝向南北-普通住宅', 'update': '2016-07-05'}
{'title': '趙巷鎮中小區 3室1廳 110平米 中等裝修 押一付三免中介(個人)', 'price': '2600', 'url': 'http://sh.58.com/zufang/26585344546231x.shtml', 'addr': '火星', 'view': '14', 'area': [], 'type': '3室1廳2衛-110m2-共5層中等裝修-朝向南北-普通住宅', 'update': '2016-07-05'}
{'title': '川沙個人民房出租(1室主臥)(個人)', 'price': '800', 'url': 'http://sh.58.com/zufang/26573907883564x.shtml', 'addr': '火星', 'view': '400', 'area': ['浦東', '川沙'], 'type': '3室1廳1衛-23m2', 'update': '2016-07-05'}
{'title': '紀育路 3室1廳2衛(個人)', 'price': '4000', 'url': 'http://sh.58.com/zufang/26363391944397x.shtml', 'addr': '火星', 'view': '373', 'area': ['閔行', '紀王'], 'type': '3室1廳2衛-110m2', 'update': '2016-07-05'}
{'title': '黃樓整棟私房出租 精裝修(個人)', 'price': '7000', 'url': 'http://sh.58.com/zufang/26505320717500x.shtml', 'addr': '火星', 'view': '250', 'area': ['浦東', '川沙'], 'type': '3室2廳3衛-170m2', 'update': '2016-07-05'}
{'title': '浦江智匯園 3室1廳1衛(中介勿擾!!!)可以隨時來看房(個人)', 'price': '4500', 'url': 'http://sh.58.com/zufang/26516734234287x.shtml', 'addr': '三魯公路聯航路', 'view': '181', 'area': ['閔行', '浦江'], 'type': '3室1廳1衛-90m2', 'update': '2016-07-05'}
{'title': '吉房出租 金江家園 3室1廳1衛 精裝全配(個人)', 'price': '5200', 'url': 'http://sh.58.com/zufang/26489326099117x.shtml', 'addr': '火星', 'view': '397', 'area': ['普陀', '長征'], 'type': '3室1廳1衛-83m2', 'update': '2016-07-05'}
{'title': '定威小區 3室1廳1衛 精裝配家具家電隨時看房(個人)', 'price': '6800', 'url': 'http://sh.58.com/zufang/21192295389454x.shtml', 'addr': '長寧定威小區28弄', 'view': '507', 'area': ['長寧', '北新涇'], 'type': '3室1廳1衛-102m2', 'update': '2016-07-05'}
{'title': '環綠國際 3室1廳1衛(個人)', 'price': '3600', 'url': 'http://sh.58.com/zufang/26517485393597x.shtml', 'addr': '寶山寶綠路99弄', 'view': '320', 'area': ['寶山', '顧村'], 'type': '3室1廳1衛-95m2', 'update': '2016-07-05'}
{'title': '嘉定安亭路勁上海派3室2廳精裝家電全配地鐵步行6分鐘押一付三(個人)', 'price': '3600', 'url': 'http://sh.58.com/zufang/25953603388845x.shtml', 'addr': '地鐵11號線昌吉東路站步行6分鐘', 'view': '582', 'area': ['嘉定', '安亭'], 'type': '3室2廳1衛-88m2-中層(共17層)精裝修-朝向南-普通住宅', 'update': '2016-07-05'}
{'title': '上南恒大華城長清 3室2廳102平米 豪華裝修(個人)', 'price': '7500', 'url': 'http://sh.58.com/zufang/19775344145546x.shtml', 'addr': '楊新路281弄20號202室', 'view': '214', 'area': ['浦東', '上南', '恒大華城長清苑'], 'type': '3室2廳1衛-102m2-低層(共6層)豪華裝修-朝向南-普通住宅', 'update': '2016-07-05'}
{'title': '陽光城愉景灣 3室2廳2衛 各人出租(個人)', 'price': '8000', 'url': 'http://sh.58.com/zufang/26433797757903x.shtml', 'addr': '火星', 'view': '189', 'area': ['浦東', '川沙'], 'type': '3室2廳2衛-111m2', 'update': '2016-07-05'}
{'title': '青浦-夏陽街道二層整租小別墅太來村3室2廳2衛120平(個人)', 'price': '1600', 'url': 'http://sh.58.com/zufang/26583997854283x.shtml', 'addr': '火星', 'view': '10', 'area': ['青浦', '夏陽街道'], 'type': '3室2廳1衛-120m2', 'update': '2016-07-05'}
{'title': '唐鎮金唐公寓 3室2廳112平米 中等裝修 押一付三(個人)', 'price': '6200', 'url': 'http://sh.58.com/zufang/19218020327818x.shtml', 'addr': '創新西路75弄1-136號', 'view': '270', 'area': ['浦東', '唐鎮', '金唐公寓'], 'type': '3室2廳2衛-112m2-中層(共6層)中等裝修-朝向南-公寓', 'update': '2016-07-05'}
{'title': '萬科vcity 3室2廳1衛(個人)', 'price': '3800', 'url': 'http://sh.58.com/zufang/22026009232408x.shtml', 'addr': '火星', 'view': '632', 'area': ['閔行', '老閔行'], 'type': '3室2廳1衛-93m2', 'update': '2016-07-05'}
{'title': '招商海德名門 3室2廳 134平米 簡單裝修(個人)', 'price': '5800', 'url': 'http://sh.58.com/zufang/26583849545134x.shtml', 'addr': '寶山區海笛路333弄', 'view': '28', 'area': ['寶山', '楊行'], 'type': '3室2廳2衛-134m2-中層(共11層)簡單裝修-朝向南北-公寓', 'update': '2016-07-05'}
{'title': '盛園 3室2廳2衛(個人)', 'price': '6600', 'url': 'http://sh.58.com/zufang/26543825556283x.shtml', 'addr': '火星', 'view': '57', 'area': ['閔行', '莘莊'], 'type': '3室2廳2衛-127m2', 'update': '2016-07-05'}
{'title': '金澤苑 3室2廳1衛(個人)', 'price': '7200', 'url': 'http://sh.58.com/zufang/26440842956482x.shtml', 'addr': '浦東菏澤路825弄', 'view': '343', 'area': ['浦東', '金橋'], 'type': '3室2廳1衛-110m2', 'update': '2016-07-05'}
{'title': '蓮康苑 3室1廳1衛(個人)', 'price': '6000', 'url': 'http://sh.58.com/zufang/26583512488879x.shtml', 'addr': '火星', 'view': '15', 'area': ['浦東', '北蔡'], 'type': '3室1廳1衛-100m2', 'update': '2016-07-05'}
{'title': '呂巷名苑精裝 3室2廳2衛(個人)', 'price': '2000', 'url': 'http://sh.58.com/zufang/26412639191747x.shtml', 'addr': '火星', 'view': '514', 'area': ['金山', '呂巷'], 'type': '3室2廳2衛-120m2', 'update': '2016-07-05'}
{'title': '崇明島 藍湖灣小高層 三房二廳 便宜出租 1000元O(個人)', 'price': '1000', 'url': 'http://sh.58.com/zufang/26452991933000x.shtml', 'addr': '火星', 'view': '464', 'area': ['崇明'], 'type': '3室2廳1衛-112m2', 'update': '2016-07-05'}
{'title': '科華公寓 3室2廳2衛 送閣樓(個人)', 'price': '13000', 'url': 'http://sh.58.com/zufang/26522471687605x.shtml', 'addr': '徐匯欽州路500弄', 'view': '145', 'area': ['徐匯', '漕河涇'], 'type': '3室2廳2衛-129m2', 'update': '2016-07-05'}
{'title': '夏陽街道雙橋公寓 3室2廳 113平米 毛坯 押一付三(個人)', 'price': '面議', 'url': 'http://sh.58.com/zufang/25069140506438x.shtml', 'addr': '盈浩路102弄3號703室', 'view': '61', 'area': ['青浦', '夏陽街道'], 'type': '3室2廳2衛-113m2-中層(共11層)毛坯-朝向南北-普通住宅', 'update': '2016-07-05'}

4. 總結

  • 網站中的部分數據是通過JS獲得的
  • tag前的#表示id
  • tag可以用.連接它的class屬性
  • 緊挨著的兩個tag>連接,如果中間有一到多個tag則用空格連接
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,268評論 25 708
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,765評論 18 399
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,923評論 18 139
  • 小時候,小姨來我家時,我總覺得她很漂亮,更有些自在的感覺。慢慢地,我大了,不時常見到她,但總聽姥姥和媽媽提起...
    不想做作家的平民閱讀 445評論 0 0
  • 1給自己設限 :被鋼鐵廠裁掉的員工,還固執地認為自己只能做鋼鐵廠的工作。他們沒有意識到,外部世界已經起了變化,即使...
    濃湯閱讀 194評論 0 1