第一周/实战作业: 抓取房屋信息

1. 引言

进入58房屋出租页面, 爬取列表页中除了推广房屋外的正常房屋信息

第一周/实战作业: 抓取房屋信息_第1张图片
Paste_Image.png
第一周/实战作业: 抓取房屋信息_第2张图片
Paste_Image.png

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

2. 分析

  • 推广房屋信息的链接中有关键字'short', 过虑掉
  • 浏览量信息要通过JS请求才能获取
第一周/实战作业: 抓取房屋信息_第3张图片
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卫-139m²-低层(共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卫-137m²-中层(共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卫-110m²-共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卫-23m²', '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卫-110m²', 'update': '2016-07-05'}
{'title': '黄楼整栋私房出租 精装修(个人)', 'price': '7000', 'url': 'http://sh.58.com/zufang/26505320717500x.shtml', 'addr': '火星', 'view': '250', 'area': ['浦东', '川沙'], 'type': '3室2厅3卫-170m²', '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卫-90m²', '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卫-83m²', '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卫-102m²', '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卫-95m²', '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卫-88m²-中层(共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卫-102m²-低层(共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卫-111m²', '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卫-120m²', '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卫-112m²-中层(共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卫-93m²', '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卫-134m²-中层(共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卫-127m²', '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卫-110m²', '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卫-100m²', '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卫-120m²', '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卫-112m²', '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卫-129m²', '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卫-113m²-中层(共11层)毛坯-朝向南北-普通住宅', 'update': '2016-07-05'}

4. 总结

  • 网站中的部分数据是通过JS获得的
  • tag前的#表示id
  • tag可以用.连接它的class属性
  • 紧挨着的两个tag>连接,如果中间有一到多个tag则用空格连接

你可能感兴趣的:(第一周/实战作业: 抓取房屋信息)