Python专题

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

2018-09-12  本文已影响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一起学习
喜欢我的文章可以关注我哦,别忘了点个喜欢!

上一篇 下一篇

猜你喜欢

热点阅读