目录

处理流程

构建脚本框架

分析租房信息生成

页面分析

具体步骤

解决图片映射问题

那么如何处理图片?

处理映射字体

数据提取

处理流程

  1. 构建脚本框架
  2. 分析租房信息生成
  3. 解决图片映射问题
  4. 数据提取

构建脚本框架

首先构建进本的脚本框架。

import requests
from lxml import etreeclass ziRoom():def __init__(self):# 匿名函数,对空列表进行取值,防止[0]异常self.LamBDa = lambda x:x[0] if x else ''def crawl(self, url):"""请求接口获取响应:param url: 请求接口:return: 响应"""headers = {'User-Agent': '写入ua'}response = requests.get(url, headers=headers)if response.status_code == 200:if flag:# 用于提取数据return response.textelse:# 用于处理图片return response.contentdef selector(self, html, path, flag=True):"""xpath提取数据:param html: html元素:param path: xpath路径:param flag: 标志位,默认解析响应数据:return: """if flag:node = etree.HTML(html)extract = node.xpath(path)else:extract = html.xpath(path)return extractdef run(self):url = '某租房网'self.crawl(url)if __name__ == '__main__':ziRoom().run()

分析租房信息生成

页面分析

字体映射图片

css接口 

由上图分析得知,下一步需要获取到图片url及px像素值,而通过图片识别的结果及px像素值也无法得出对应的映射字体,还需找到另外一个值background-size: auto 20px

分析多家租房价格后,发现图片是同一张。但为了防止后面有差别,将图片url全部提取出来,一对一处理。

注意:价格固定,但图片和像素值是动态变化的,只要最终计算的结果与房源对应且价格一直,就说明成功了。

具体步骤

  1. 获取图片url、px像素值、size像素值;
  2. 请求获取图片content并进行识别,得到映射字体字符串/列表;
  3. 通过px像素值、size像素值之间的计算得出映射字体字符串/列表的索引值。

注意:px像素值需要转为int做计算,提取的类型str且为浮点型字符串,无法直接str转为int。

解决方法:使用float()转为浮点型即可。

通过我的测试得出计算:取整,int(float(px像素值)//int(background-size))。

解决图片映射问题

通过前面分析,需要处理图片映射,大概思路就是将图片中的数字整合成一个字典或字符串,通过像素值进行提取。

那么如何处理图片?

这里我们需要用到ocr图像识别技术。推荐两种ocr识别库:ddddocr、tesseract。

# ddddocr安装
pip install ddddocr=1.4.0# pytesseract安装
# 比较繁琐需要添加配置,不添加每次编写脚本使用时都要编写配置项
pip install pytesseract
# 配置
# 1、环境变量:Administrator用户变量 > 新建 > {变量名:TESSDATA_PREFIX, 变量值: tessdata路径D:\Tesseract-OCR\tessdata}
# 2、修改文件:pytesseract.py > 搜索'cmd'找到并修改tesseract_cmd = r'D:\Tesseract-OCR\tesseract.exe'  # tesseract_cmd为tesseract执行文件路径# 模块导入
import ddddocr
import pytesseract

处理映射字体

    def parse(self, response):divs = self.selector(html=response, path='//div[@class="Z_list-box"]/div[@class="item"]')# 所有价格加密图片for div in divs:# 房源价格# ??? # 处理价格:获取price的style属性items = self.selector(flag=False, html=div, path='.//div[@class="price "]//span[@class="num"]/@style')priPicUrl = []  # 当前价格字体映射图片priPicPx = []   # 对应的像素值for item in items:# 提取价格字体映射图片,与对应的像素值pri = self.LamBDa(re.findall('url\((.*?)\);background-position: -(.*?)px', item))pUrl = 'https:' + pri[0]pPx = pri[1]# 如果存在,说明图片相同,就不存储了# if pUrl not in priPicUrl:#     priPicUrl.append(pUrl)# 防止后面有差别,全部提取出来,一对一处理。priPicUrl.append(pUrl)priPicPx.append(float(pPx))  # 像素值需要做计算# 提取background-sizesizeHref = self.selector(html=response, path='//head/link[@rel="stylesheet"]/@href')sizeCssurl = 'https:' + self.LamBDa([href for href in sizeHref if 'list.css?' in href])backgroundSize = int(self.LamBDa(re.findall('background-size:auto (.\d+)px', self.crawl(url=sizeCssurl))))"""ddddocr使用(简单)"""# 创建ocr识别对象,show_ad=False(进入源码你就明白了)ocr = DdddOcr(show_ad=False)# 识别图片获取映射字体mapCharocrImg = [self.crawl(url=url, flag=False) for url in priPicUrl]# 直接读取字节mapChar = [ocr.classification(o) for o in ocrImg]"""tesseract使用(繁琐)mapChar = []  # 用于存放识别的字符串ocrImg = [self.crawl(url=url, flag=False) for url in priPicUrl]for o in ocrImg:# 需要将字节保存为图片,使用Image模块读取,最终识别也会出现空格换行等符号with open('o.png', 'wb') as f:f.write(o)mapChar.append(pytesseract.image_to_string(Image.open('o.png')).replace(' ', '').replace('\n', ''))"""# 计算:int(float(px像素值)//int(background-size))  取整price = priText.replace('¥', '¥'+''.join([mapChar[i][int(priPicPx[i]//20)] for i in range(len(mapChar))]))

数据提取

整理代码,完成租房信息数据的提取

import requests
from lxml import etree
import re
from ddddocr import DdddOcr
import pytesseract  # 还需要使用Image图片处理
from PIL import Image  # 图片处理class ziRoom():def __init__(self):# 匿名函数,对空列表进行取值,防止[0]异常self.LamBDa = lambda x:x[0] if x else ''def crawl(self, url, flag=True):"""请求接口获取响应:param url: 请求接口:return: 响应"""headers = {'User-Agent': '添加ua'}response = requests.get(url, headers=headers)if response.status_code == 200:if flag:# 用于提取数据return response.textelse:# 用于处理图片return response.contentdef selector(self, html, path, flag=True):"""xpath提取数据:param html: html元素:param path: xpath路径:param flag: 标志位,默认解析响应数据:return: xpath提取的数据"""if flag:node = etree.HTML(html)extract = node.xpath(path)else:extract = html.xpath(path)return extractdef parse(self, response):"""解析页面:param response: 接口响应:return:"""# 取出当前页面 所有 客源标签 的 价格标签 --> 每家客源的价格标签divs = self.selector(html=response, path='//div[@class="Z_list-box"]/div[@class="item"]')# 所有价格加密图片for div in divs[:2]:# 房源图片roomPic = 'https:' + self.LamBDa(self.selector(flag=False, html=div, path='.//img[@class="lazy"]/@src'))# 房源名  ['整租·星河城东区2室1厅-西南'] 当前标签下(.//)   # h5标签的class不同,不可添加[@class] 否则丢失数据roomName = self.LamBDa(self.selector(flag=False, html=div, path='.//h5/a/text()'))# 房源信息  # 97.62㎡ | 16/20层 > 房源距草桥站步行约702米desc = self.LamBDa(self.selector(flag=False, html=div, path='.//div[@class="desc"]')).xpath('string(.)').strip().replace('\n', '').replace(' ','').replace('\t\t\t',' > ')# 房源标签  # 自如客转租 | 离地铁近 | 木棉6.0tag = self.LamBDa(self.selector(flag=False, html=div, path='.//div[@class="tag"]')).xpath('string(.)').strip().replace('\n', '').replace(' ','').replace('\t\t\t\t\t',' | ')# 房源价格# ??? 那先提取文本 在处理价格# 1 提取文本priText = self.LamBDa(self.selector(flag=False, html=div, path='.//div[@class="price "]')).xpath('string(.)').strip().replace('\n', '').replace(' ','').replace('\t\t\t\t','')# 2 处理价格:获取price的style属性items = self.selector(flag=False, html=div, path='.//div[@class="price "]//span[@class="num"]/@style')priPicUrl = []  # 当前价格字体映射图片priPicPx = []   # 对应的像素值for item in items:# 提取价格字体映射图片,与对应的像素值pri = self.LamBDa(re.findall('url\((.*?)\);background-position: -(.*?)px', item))pUrl = 'https:' + pri[0]pPx = pri[1]# 如果存在,说明图片相同,就不存储了# if pUrl not in priPicUrl:#     priPicUrl.append(pUrl)# 防止后面有差别,全部提取出来,一对一处理。priPicUrl.append(pUrl)priPicPx.append(float(pPx))  # 像素值需要做计算# 提取background-sizesizeHref = self.selector(html=response, path='//head/link[@rel="stylesheet"]/@href')sizeCssurl = 'https:' + self.LamBDa([href for href in sizeHref if 'list.css?' in href])backgroundSize = int(self.LamBDa(re.findall('background-size:auto (.\d+)px', self.crawl(url=sizeCssurl))))"""ddddocr使用(简单)"""# 创建ocr识别对象,show_ad=False(进入源码你就明白了)ocr = DdddOcr(show_ad=False)# 识别图片获取映射字体mapCharocrImg = [self.crawl(url=url, flag=False) for url in priPicUrl]# 直接读取字节mapChar = [ocr.classification(o) for o in ocrImg]"""tesseract使用(繁琐)mapChar = []  # 用于存放识别的字符串ocrImg = [self.crawl(url=url, flag=False) for url in priPicUrl]for o in ocrImg:# 需要将字节保存为图片,使用Image模块读取,最终识别也会出现空格换行等符号with open('o.png', 'wb') as f:f.write(o)mapChar.append(pytesseract.image_to_string(Image.open('o.png')).replace(' ', '').replace('\n', ''))"""# 计算:int(float(px像素值)//int(background-size))  取整price = priText.replace('¥', '¥'+''.join([mapChar[i][int(priPicPx[i]//20)] for i in range(len(mapChar))]))# 结果print('-' * (len(roomPic) * 3 // 2) + '\n', '\t' + roomPic + '\n', '\t' + roomName,' ' * len(roomName), price + '\n', '\t' + desc + '\n', '\t' + tag + '\n', '-' * (len(roomPic) * 3 // 2))def run(self):for p in range(1, 11):url = 'https://www.租房网.com/z/p(p)/'response = self.crawl(url)self.parse(response)if __name__ == '__main__':ziRoom().run()

日常随笔,若有侵权,请联系删除。

图片映射字体反爬-某租房网相关推荐

  1. 爬取在线全面小说网小说(字体反爬)

    小说网字体反爬 小说网址:https://www.tianhuajinshu.com/ 在手机端浏览小说时,有时候开启无图模式发现部分文字加载不出来,还有的不能使用浏览自带的阅读模式进行阅读,也就是无 ...

  2. python爬虫进阶-大众点评店铺信息(字体反爬-静态映射)

    目的 获取大众点评店铺信息 详细需求 http://www.dianping.com/shenzhen/ch10 思路解析 一 通过F12查找目标信息位置,进行分析 同理进行其他信息的解析,分析汇总 ...

  3. python爬虫进阶-汽车之家贴吧信息(字体反爬-动态映射)

    目的 获取汽车之家贴吧的内容信息 详细需求 汽车之家贴吧 思路解析 一.F12获取目标信息-进行分析 二.字体反爬解析-根据上一篇的文章,直接搜索关键词就好 三 根据其后的链接,保存为ttf在本地,查 ...

  4. python爬虫笔记五:汽车之家贴吧信息(字体反爬-动态映射)

    学习网址: https://jia666666.blog.csdn.net/article/details/108974149 ----------------------------------- ...

  5. python爬虫爬取58网站数据_Python爬虫,爬取58租房数据 字体反爬

    Python爬虫,爬取58租房数据 这俩天项目主管给了个爬虫任务,要爬取58同城上福州区域的租房房源信息.因为58的前端页面做了base64字体加密所以爬取比较费力,前前后后花了俩天才搞完. 项目演示 ...

  6. 爬虫逆向学习(二):那些年遇到的花式字体反爬

    常见字体反爬破解策略 CSS偏移反爬虫 案例场景 破解策略 SVG字体反爬 案例场景 破解策略 自定义字体反爬 案例场景 破解策略 CSS偏移反爬虫 案例场景 css偏移反爬虫是通过样式left偏移覆 ...

  7. 斗鱼关注人数爬取 | 字体反爬的攻与防

    作者:CJ Ting 原文:https://cjting.me/2020/07/01/douyu-crawler-and-font-anti-crawling/ 之前因为业务原因需要爬取一批斗鱼主播的 ...

  8. 反爬终极方案总结---字体反爬

    最近临时受命,要针对采集我司网站的爬虫进行反制.虽然不太熟悉这个领域,但既然分到咱这儿了,那就上呗,有啥说的,谁让咱是"全栈工程师"呢(牛逼吹的大了点). 原本公司已经有了一套字体 ...

  9. 前端电子表数字字体_爬虫:如何优雅应对字体反爬

    目录 THE BEGIN 一 什么是字体反爬 二 如何解密 1.人工解密 2.工具解密 三 建立映射关系 四 解密 THE BEGIN 网页数据爬取可以简单分为三步:抓取页面,分析页面,存储数据.其中 ...

最新文章

  1. Hashtable的使用
  2. W ndoWs7更新怎么关闭,怎么样取消windows7自动更新
  3. 服务 进程守护 MarsDaemon 简介
  4. 比0 冷1度c语言编程,关于DS18B20的C语言程序(精确度0.1度).doc
  5. python socket udp并发_Python进阶----UDP协议使用socket通信,socketserver模块实现并发
  6. 量化延时法时间测量_干货分享:直线度测量发展及几种方法详解
  7. Python(65)_写函数,判断用户传入列表的长度,若大于2,则仅保留前两个长度的内容,并将其返回给调用者...
  8. 将一个文本文件的内容按行读出,每读出一行就顺序加上行号,并写入到另一个文件中。...
  9. 51单片机redefinition_关于c51单片机的一个问题
  10. Java操作数据库(一,JDBC的入门)
  11. cad尺寸标注快捷键_CAD快速标注方法你知道几种?
  12. 卸载WPS后Office文档图标显示异常
  13. 怎么设置微信公众号自动回复蓝色字体小程序链接
  14. 如何看待花呗接入央行个人征信?
  15. 我的世界手机java版下载_我的世界java版下载手机版-我的世界java版手机版v1.16 - 手机迷...
  16. 概率论05 - 随机变量及其分布函数
  17. 全球及中国DIN 2353压缩配件行业研究及十四五规划分析报告
  18. oracle重做日志教程,Oracle重做日志管理
  19. Android上多进程中使用webview的问题
  20. 程序员的呐喊--读书感悟

热门文章

  1. 【精益生产】精益知识大全
  2. 《数据库系统概论》课程指南
  3. 通过matlab对比不同调制方式下的球形译码误码率仿真,包括BPSK,QPSK,8PSK,4QAM以及16QAM
  4. 华师大计算机博士难考吗,华南师范大学博士难考吗,华南师范大学与华中师范大学哪一个好?...
  5. java模拟回合制游戏大小姐_[源码和文档分享]基于java的RPG回合制游戏
  6. 后疫情时代,VR购物—零售业的硬核破局之道
  7. windows无法启动MySQL服务(位于本地计算机上)。错误1067:进程意外终止
  8. .Net国际化多语言简单实现
  9. 企业微信小助理,企业微信营销软件,企业微信hook协议
  10. 中山大学计算机博士_中山大学数据科学与计算机学院2019申请审核制博士招生简章...