美文网首页
第一周/实战作业: 抓取房屋信息

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

作者: uvscjh | 来源:发表于2016-07-05 16:11 被阅读47次

    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卫-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则用空格连接

    相关文章

      网友评论

          本文标题:第一周/实战作业: 抓取房屋信息

          本文链接:https://www.haomeiwen.com/subject/lxihjttx.html