美文网首页Python专题
2018年9月12日 自如项目---阶段(一)---价格获取

2018年9月12日 自如项目---阶段(一)---价格获取

作者: 右哼哼丨左哼哼 | 来源:发表于2018-09-12 17:52 被阅读192次

    有段时间 群里聊到了自如网站的价格用采集器采集不了,所以自己想看看什么原因导致的
    参考链接:http://sz.ziroom.com/z/vr/61127945.html

    我们查看源代码网页,发现代码中并未含有价格信息,而是通过一张随机的图片,再利用Css样式偏移组合得到价格

    image.png

    我们查看ajax加载,发现info?id=61127945&house_id=60179749这一条加载中包含了价格的相关信息,具体如下图所示

    image.png

    这样我们就得到了价格的坐标,所以我们可以考虑使用pytesseract来识别图片中的数字,然后根据价格索引得到价格

    那么如何请求这个ajax呢? 我们观察一下请求信息

    image.png

    我们可以通过访问网页的URL轻易获取到房间ID,那么房子的ID怎么获取呢?我们去源代码找一找

    image.png

    如何获取这个网页呢? 没什么难度 直接get你当前访问的URL就行了

    image.png

    我们来捋一捋我们要做的事情:

    1. 先get网页url,利用正则获取到房间ID和房子ID
    2. 根据得到的2个ID,请求ajax,得到价格图片和价格索引信息
    3. 利用pytesseract 识别图中数字信息,根据价格索引得到最终的房价

    网页分析到这里就结束了,接下里我们看代码

    所需要使用的包

    image.png

    get当前网页,返回房间ID和房子ID

    image.png

    根据2个ID 请求ajax,返回图片和索引

    image.png

    核心部分,使用pytesseract,识别图片信息,并根据价格索引,返回正确的房价

    image.png

    我们来跑一跑这个程序试试看!

    image.png

    程序源码:

    from PIL import Image
    import pytesseract
    import requests
    import re
    import time
    
    
    class ZrPrApi(object):
        '''
        通过给定URL,爬取自如网站房源价格
        '''
        # 网络请求初始化
        headers = {
            # 'Host': 'sz.ziroom.com',
            'Referer': 'http://sz.ziroom.com',
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
        }
    
        def get_houseID(self, url, S):
            '''
            根据给定的URL,解析对应的houseID和roomID
            '''
            res = S.get(url, headers=self.headers)
            # 先判断返回状态码,既可以快速定位出错原因,又减少程序冗余运行
            if res.status_code == 200:
                res.encoding = 'utf-8'
                # 解析url得到roomID
                roomID = re.findall("/(\d+).html", url)
                # 解析请求url返回的info,得到houseID
                houseID = re.findall("'houseid', (.*?)]", res.text)
                # 判断houseID是否有效数据
                if houseID:
                    # 这里以字典方式返回主函数(不一定非要用字典的方式)
                    return dict([('roomID', roomID[0]), ('houseID', houseID[0])])
                # 程序异常后,快速排错
                else:
                    print('URL:', url)
                    print('roomID:', roomID)
                    print('houseID:', houseID)
                    print('网页异常,程序终止')
                    exit()
            # 状态码异常 可以考虑使用IP代理
            else:
                print('get_houseID异常:%s' % res.status_code)
                exit()
    
        def get_priceImg(self, info, S):
            '''
            获取价格图片,准备下一步的图文识别
            '''
            url = 'http://sz.ziroom.com/detail/info?id=%s&house_id=%s' % (info['roomID'], info['houseID'])
            # 使用requests.Session()的好处,不用关心cookies的更新问题
            res = S.get(url, headers=self.headers)
            res.encoding = 'utf-8'
            print(res.url)
            # 还是判断状态码,理由同上
            if res.status_code == 200:
                temp = res.json()
                # 取大图URL,方便图像识别
                img_url = temp['data']['price'][1]
                # 取价格图片索引值
                img_value = temp['data']['price'][2]
                return [img_url, img_value]
            else:
                print('get_priceImg异常:%s' % res.status_code)
                exit()
    
        def get_price(self, imgs, S):
            '''
            获取价格图片,图文识别后返回房源价格
            '''
            data = S.get('http:' + imgs[0])
            # 判断网页状态码
            if data.status_code == 200:
                # 利用时间戳给文件命名,非(lan)常(dao)科(jia)学(le)
                filename = str(time.time()) + '.png'
                with open(filename, 'wb') as f:
                    f.write(data.content)
                # 核心科技部分:图文识别及价格索引拼接
                text = pytesseract.image_to_string(Image.open(filename))
                temp = []
                for i in imgs[1]:
                    temp.append(text[i])
                price = ''.join(temp)
                return price
            else:
                print('get_price异常:%s' % data.status_code)
    
    
    if __name__ == '__main__':
        # 标记程序启动时间
        start = time.clock()
        # 使用会话,连续访问多个网页,防止网页因cookies不同而采集信息失败
        S = requests.Session()
        zr = ZrPrApi()
        # 获取houseID,以便下一步请求价格图片地址
        info = zr.get_houseID('http://sz.ziroom.com/z/vr/61127945.html', S)
        # 获取图片地址,以便下一步分析价格
        imgs = zr.get_priceImg(info, S)
        # 图文识别,得到最终价格
        print(zr.get_price(imgs, S))
        # 标记程序结束时间
        end = time.clock()
        # 打印程序耗时
        print(end - start)
    
    

    下一期讲述:获取自如详情页房间配置信息提取


    喜欢学习python爬虫的朋友,可以加交流群:692-858-412一起学习
    喜欢我的文章可以关注我哦,别忘了点个喜欢!

    相关文章

      网友评论

      本文标题:2018年9月12日 自如项目---阶段(一)---价格获取

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