zoukankan      html  css  js  c++  java
  • 如何高效地爬取链家的房源信息(三)

    Python实现的链家网站的爬虫第三部分。


    本系列文将以链家南京站为例,使用Python实现链家二手房源信息的爬虫,将数据爬取,并存入数据库中,以便使用。


    本系列第一部分为基础:

    如何高效地爬取链家的房源信息(一)


    本系列第二部分为爬取小区信息:

    如何高效地爬取链家的房源信息(二)



    本文是第三部分,爬取在售二手房信息并存入数据库,部分代码依赖于第一部分,同时依赖于第二部分的结果。


    在前文中已经获取了小区信息,并存在了数据库中,直接读库遍历小区进行爬取:

    def do_xiaoqu_zaishou_spider(db_xq,db_zs):

        """

        批量爬取小区在售

        """

        count=0

        xq_list=db_xq.fetchall()

        for xq in xq_list:

            xiaoqu_zaishou_spider(db_cj,xq[0])

            count+=1

            print ('have spidered zaishou %d xiaoqu %s' % (count,xq[0]))

        print( 'done')


    对某一个小区内的所有在售房源进行爬取,需要分页:

    def xiaoqu_zaishou_spider(db_cj, xq_url=u"https://nj.lianjia.com/xiaoqu/1411000000391/"):

        """

        爬取小区在售

        """

        url = xq_url.replace('xiaoqu/','ershoufang/c');

        try:

            req = urllib.request.Request(url, headers=hds[random.randint(0, len(hds) - 1)])

            source_code = urllib.request.urlopen(req, timeout=10).read()

            plain_text = source_code.decode('utf-8')

            soup = BeautifulSoup(plain_text,"html.parser")

        except (urllib.request.HTTPError, urllib.request.URLError) as e:

            print(e)

            exception_write('xiaoqu_zaishou_spider', xq_url)

            return

        except Exception as e:

            print(e)

            exception_write('xiaoqu_zaishou_spider', xq_url)

            return

        content = soup.find('div', {'class': 'page-box house-lst-page-box'})

        total_pages = 0

        if content:

            d = "d=" + content.get('page-data')

            loc = {}

            glb = {}

            exec(d, glb, loc);

            total_pages = loc['d']['totalPage']


        threads = []

        for i in range(total_pages):

            tmp= u'ershoufang/pg%dc'% (i + 1)

            url_page = url.replace('ershoufang/c',tmp);

            t = threading.Thread(target=zaishou_spider, args=(db_cj, url_page))

            threads.append(t)

        for t in threads:

            t.start()

        for t in threads:

            t.join()


    爬取单个页面内的在售信息:

    def zaishou_spider(db_cj, url_page=u"https://nj.lianjia.com/chengjiao/pg4c1411000000142/"):

        """

        爬取页面链接中的在售

        """

        try:

            req = urllib.request.Request(url_page, headers=hds[random.randint(0, len(hds) - 1)])

            source_code = urllib.request.urlopen(req, timeout=10).read()

            plain_text = source_code.decode('utf-8');

            soup = BeautifulSoup(plain_text,"html.parser")

        except (urllib.request.HTTPError, urllib.request.URLError) as e:

            print(e)

            exception_write('zaishou_spider', url_page)

            return

        except Exception as e:

            print(e)

            exception_write('zaishou_spider', url_page)

            return


        cjs = soup.find('ul', {'class': 'sellListContent'});

        cj_list = cjs.findAll('li', {})

        for cj in cj_list:

            info_dict = {}

            title = cj.find('div', {'class': 'title'});

            houseInfo = cj.find('div', {'class': 'houseInfo'});

            positionInfo = cj.find('div', {'class': 'positionInfo'});

            followInfo = cj.find('div', {'class': 'followInfo'});

            tag = cj.find('div', {'class': 'tag'});

            totalPrice = cj.find('div', {'class': 'totalPrice'});

            unitPrice = cj.find('div', {'class': 'unitPrice'});


            href = title.find('a')

            if not href:

                continue

            info_dict.update({u'链接': href.attrs['href']})

            content = title.text

            info_dict.update({u'房子描述': content})



            content = houseInfo.text.split('|')  

    #有可能有别墅项,有可能无部分项

            if content:

                info_dict.update({u'小区名称': content[0].strip()})

                if content[1].find(u'墅') != -1:

                    i=1;

                else:

                    i=0;

                if len(content) >= 2+i:

                    info_dict.update({u'户型': content[1+i].strip()})

                if len(content) >= 3+i:

                    info_dict.update({u'面积': content[2+i].strip()})

                if len(content) >= 4+i:

                    info_dict.update({u'朝向': content[3+i].strip()})

                if len(content) >= 5+i:

                    info_dict.update({u'装修': content[4+i].strip()})

                if len(content) >= 6+i:

                    info_dict.update({u'电梯': content[5+i].strip()})


            content = positionInfo.text.split('-')

            if len(content) >= 2:

                info_dict.update({u'楼层年代楼型': content[0].strip()}) 

                info_dict.update({u'区域': content[1].strip()})  

            else:

                info_dict.update({u'区域': content[0].strip()})  


            content = followInfo.text.split('/')

            for cont in content:

                if cont.find(u'关注') != -1:

                    info_dict.update({u'关注': cont.strip()})

                elif cont.find(u'带看') != -1:

                    info_dict.update({u'带看': cont.strip()})

                elif cont.find(u'发布') != -1:

                    info_dict.update({u'发布时间': cont.strip()})


            if tag != None:

                tagall=tag.findAll('span')

                for span in tagall:

                    if span.attrs['class'][0] ==u'taxfree':

                        info_dict.update({u'税费': span.text})  # 满几年

                    elif span.attrs['class'][0] ==u'subway':

                        info_dict.update({u'地铁': span.text})

                    elif span.attrs['class'][0] ==u'haskey':

                        info_dict.update({u'限制': span.text})


            info_dict.update({u'挂牌价': totalPrice.text})

            info_dict.update({u'挂牌单价': unitPrice.text})


            command = gen_zaishou_insert_command(info_dict)

            db_zs.execute(command, 1)


    爬取的在售房源信息将被存储到数据库表中。




    在接下来将说明如何爬取历史成交二手房信息,敬请期待。


    640?wx_fmt=jpeg

    长按进行关注。


  • 相关阅读:
    android listview 的弹性滑动 简单demo 实现
    android轻松监听来电和去电
    android有效的获取图像和视频
    android项目源码异步加载远程图片的小例子
    Android游戏开发系统控件CheckBox
    Android Gallery3D效果 教程 案例 代码
    Android 桌面组件【app widget】 进阶项目心情记录器
    基于ListView和CheckBox实现多选和全选记录的功能
    Android上传文件到服务器中的简单实例
    最小边覆盖(最小路径覆盖)(路径可相交)——pku2594
  • 原文地址:https://www.cnblogs.com/protosec/p/11673336.html
Copyright © 2011-2022 走看看