点击上方“Python爬虫与数据挖掘”,进行关注

回复“书籍”即可获赠Python从入门到进阶共10本电子书

松下问童子,言师采药去。

大家好,我是小小明,今天看到一个网站:

太神奇了,对于每个数字都用css背景图片裁切得到一张小图进行显示。可以确定的是每个数字的图片大小是8*17。

今天我们就一起玩玩。

开始测试

先尝试用request读取数据,结果获得一大堆极度混淆的JS的代码。然后尝试用selenium访问,结果:

感觉这个防火墙有点叼。

算了,使用大杀器来隐藏模拟浏览器的特征:

from selenium.webdriver import ChromeOptions
from selenium import webdriver
browser = webdriver.Chrome()option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
option.add_experimental_option('useAutomationExtension', False)
option.add_argument('user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36')
option.add_argument("--disable-blink-features=AutomationControlled")
browser = webdriver.Chrome(options=option)with open('stealth.min.js') as f:js = f.read()
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {'source': js
})
url = 'http://hotels.huazhu.com/inthotel/detail/9005308'
browser.get(url)

这回页面总算是出来了:

然而价格有时并不显示,只能多刷新几下页面:

多次访问之后,数据总算能看到了。

下面让模拟器模拟点击查看全部价格:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECwait = WebDriverWait(browser, 10)table = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#Pdetail_part2 table')))
table.location_once_scrolled_into_view
{'x': 0, 'y': 0}
more_click = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#Pdetail_part2 a[class="viewallprice"]')))
more_click.click()

这样7条价格数据,我们就全部能够看到了。

下面我们开始抓取我们需要的数据:

截图获取需要的数据

from io import BytesIO
import base64
from PIL import Imagefor tr in table.find_elements_by_css_selector("table tr[class^='room first']"):print(tr.find_element_by_tag_name("h3").text)price = tr.find_element_by_css_selector("div>a[class^='totalprice']")img_data = base64.b64decode(price.screenshot_as_base64)img = Image.open(BytesIO(img_data))display(img)

调整鼠标滑动的位置后再来一次:

说明截图有时截的并不准确,想要精准截图也非常困难,因为无法通过程序准确滚动到应该的位置。

光截图就能搞定,那就太简单了。

本文的主要目前还是为了演示解析CSS,咱们继续采用解析法来获取数据:

解析CSS获取图片数据

首先我们解析出我们需要的数据:

img_url = None
for tr in table.find_elements_by_css_selector("table tr[class^='room first']"):name = tr.find_element_by_tag_name("h3").textprint(name)price = tr.find_element_by_css_selector("div>a[class^='totalprice']")for var in price.find_elements_by_tag_name("var"):if img_url is None:img_url = var.value_of_css_property("background-image")[5:-2]print(img_url)position = var.value_of_css_property("background-position")w, h = map(lambda x: int(x[1:-2]), position.split())print(w, h)
高级大床房
http://hotels.huazhu.com/Blur/Pic?b=81efc0b8e3094942a81d01e311864270
170 2
188 2
126 2
豪华大床房
170 2
33 2
56 2
豪华双床房
145 2
2 2
188 2
观景豪华大床房
145 2
170 2
111 2
行政大床房
33 2
56 2
56 2
行政双床房
201 2
2 2
145 2
行政套房
2 2
2 2
33 2
188 2

尝试下载CSS背景图片:

browser.get(img_url)

结果又是被腾讯T-Sec Web应用防火墙(WAF)拦截的页面,说明直接用selenium下载图片行不通。

用request下载呢?经尝试也老是被拦截。

最终,写出了如下代码(还能较为顺利的获取图片数据):

import requests
from io import BytesIO
import base64
from PIL import Imagedef download_img(img_url):cookies = {o['name']: o['value'] for o in browser.get_cookies()}headers = {"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9","Accept-Encoding": "gzip, deflate","Accept-Language": "zh-CN,zh;q=0.9","Cache-Control": "max-age=0","Connection": "keep-alive","Host": "hotels.huazhu.com","Upgrade-Insecure-Requests": "1","User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"}for _ in range(10):r = requests.get(img_url, headers=headers, cookies=cookies)if r.status_code == 200:breakelse:return Noneimg = Image.open(BytesIO(r.content))return img
img = download_img(img_url)
img

有了图片,我们就可以裁剪出相应的数字图片并进行拼接了。

对最后一条数据进行测试:

可以看到解析和拼接的效果非常不错。

然后测试批量的数据提取:

img_url = None
for tr in table.find_elements_by_css_selector("table tr[class^='room first']"):name = tr.find_element_by_tag_name("h3").textprint(name)price = tr.find_element_by_css_selector("div>a[class^='totalprice']")var_el_s = price.find_elements_by_tag_name("var")n = len(var_el_s)target = Image.new('RGB', (10 * n, 17), color=(255, 255, 255))for i, var in enumerate(var_el_s):if img_url is None:img_url = var.value_of_css_property("background-image")[5:-2]img = download_img(img_url)position = var.value_of_css_property("background-position")w, h = map(lambda x: int(x[1:-2]), position.split())r = img.crop((w, h, w+8, h+17))target.paste(r, (10*i, 0), r)display(target)

可以看到已经顺利的得到了需要的结果,与网站看到的数据一致:

剩下的我们仅仅只需要对拼接好的图片进行图像识别即可,或者就直接原有图片形式保存。

图像识别

关于图像识别,有在线识别和离线识别两种方式。在线文字可以考虑使用百度云,腾讯云等,根据官网提供的接口进行操作。

下面呢,我们尝试进行离线文字识别,离线文字识别的准确率往往不如在线。

为了更好的识别效果,我们先对图片进行二值化处理:

def image_binarization(im, threshold=250):Lim = im.convert("L")table = [0 if i < threshold else 1 for i in range(256)]return Lim.point(table, "1")image_binarization(target)

下面我们需要安装pytesseract和Tesseract-OCR。

pytesseract是一个Python库:

pip insatll pytesseract

Tesseract-OCR则需要在https://digi.bib.uni-mannheim.de/tesseract/下载安装包。

由于网络原因,我在https://www.liangchan.net/liangchan/11545.html下载了一个。

项目地址:https://github.com/tesseract-ocr/tesseract

安装完成后,添加安装路径到path环境变量,命令行执行后出现如下提示说明安装成功:

C:\Users\ASUS>tesseract -v
tesseract v5.0.0.20190623leptonica-1.78.0libgif 5.1.4 : libjpeg 8d (libjpeg-turbo 1.5.3) : libpng 1.6.34 : libtiff 4.0.9 : zlib 1.2.11 : libwebp 0.6.1 : libopenjp2 2.3.0Found AVX2Found AVXFound SSEC:\Users\ASUS>

然后我们开始识别:

import pytesseracttext = pytesseract.image_to_string(image_binarization(target)).strip()
print(text)
1183

于是可以开始进行批量识别了:

import pytesseractfor tr in table.find_elements_by_css_selector("table tr[class^='room first']"):name = tr.find_element_by_tag_name("h3").textprice = tr.find_element_by_css_selector("div>a[class^='totalprice']")var_el_s = price.find_elements_by_tag_name("var")n = len(var_el_s)target = Image.new('RGB', (10 * n, 17), color=(255, 255, 255))for i, var in enumerate(var_el_s):if img_url is None:img_url = var.value_of_css_property("background-image")[5:-2]img = download_img(img_url)position = var.value_of_css_property("background-position")w, h = map(lambda x: int(x[1:-2]), position.split())r = img.crop((w, h, w+8, h+17))target.paste(r, (10*i, 0), r)display(target)text = pytesseract.image_to_string(image_binarization(target)).strip()print(name, text)

从结果可以看到,识别的准确率还是非常高的,至少目前看到的全部都正确了。

版权声明:本文为CSDN博主「小小明-代码实体」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/as604049322/article/details/118401598

小伙伴们,快快用实践一下吧!如果在学习过程中,有遇到任何问题,欢迎加我好友,我拉你进Python学习交流群共同探讨学习。

------------------- End -------------------

往期精彩文章推荐:

  • 补充篇:盘点6种使用Python批量合并同一文件夹内所有子文件夹下的Excel文件内所有Sheet数据

  • 盘点4种使用Python批量合并同一文件夹内所有子文件夹下的Excel文件内所有Sheet数据

  • 手把手教你使用Python网络爬虫实现邮件定时发送(附源码)

  • 番外篇:分享一道用Python基础+蒙特卡洛算法实现排列组合的题目(附源码)

欢迎大家点赞,留言,转发,转载,感谢大家的相伴与支持

想加入Python学习群请在后台回复【入群

万水千山总是情,点个【在看】行不行

/今日留言主题/

随便说一两句吧~~

Python处理超强反爬(TSec防火墙+CSS图片背景偏移定位)相关推荐

  1. python + selenium +pyquery 爬虫 爬取 1688详情图片 阿里巴巴详情图片 与标题 下载图片并进行压缩

    python + selenium +pyquery 爬虫  爬取 1688详情图片 阿里巴巴详情图片 与标题 下载图片并进行压缩 用到的库和源码下载地址 需要用到chromedriver  包含wi ...

  2. Python爬虫实战之爬取网站全部图片(一)

    Python爬虫实战之爬取网站全部图片(二) Python爬虫实战之通过ajax获得图片地址实现全站图片下载(三) 一.获得图片地址 和 图片名称 1.进入网址之后 按F12  打开开发人员工具点击e ...

  3. python爬虫常见反爬措施_爬虫常见的反爬措施有哪些

    爬虫常见的反爬措施有三种: 1.header头部信息 解决方法: 加User-Agent值: 如果不加header头,部分网站服务器判断不到用户的访问来源,所以会返回一个404错误来告知你是一个爬虫, ...

  4. Python | 常见的反爬及解决方法,值得收藏

    我们都知道Python用来爬数据,为了不让自家的数据被别人随意的爬走,你知道怎么反爬吗?今天播妞带着大家一起见识见识常见的反爬技术. 很多人学习python,不知道从何学起. 很多人学习python, ...

  5. Python爬虫实战——反爬机制的解决策略【阿里】

    这一次呢,让我们来试一下"CSDN热门文章的抓取". 话不多说,让我们直接进入CSND官网. (其实是因为我被阿里的反爬磨到没脾气,不想说话--) 一.URL分析 输入" ...

  6. python爬虫基本反爬

    一 最基本的User-Agentyan验证 如果通过程序向目标网站发送请求且不设置任何请求参数,服务器得到请求会识别为非人为通过浏览器请求,这种情况下大可能会被浏览器拒绝请求.(请求状态码非200,服 ...

  7. Python爬虫|反爬初体验

    前言:使用Python爬虫是当下最火的一种获取数据的方式,当我们对一些小型网站进行爬取的时候往往没什么阻碍,而当我们爬取大型网站的时候经常会遇到禁止访问.封禁IP的情况,这也是我们触发反爬机制的体现, ...

  8. python 破解字体反爬 (一)

    爬取一些网站的信息时,偶尔会碰到这样一种情况:网页浏览显示是正常的,用python爬取下来是乱码,F12用开发者模式查看网页源代码也是乱码.这种一般是网站设置了字体反爬 这里我们以58同城为例: 点击 ...

  9. python ttfont_58 字体反爬攻略 python3

    1.下载安装包 pip install fontTools 2.下载查看工具FontCreator 百度后一路傻瓜式安装即可 3.反爬虫机制 网页上看见的 后台源代码里面的 从上面可以看出,生这个字变 ...

最新文章

  1. java正则截取xml节点_实例讲述Java使用正则表达式截取重复出现的XML字符串功能...
  2. 获取DataRow某列的值的封装
  3. C++入门之常量与变量
  4. 阿里云服务器从购买,备案,安装部署中遇到的一些坑
  5. input组件android,React-Native TextInput组件详解及实例代码
  6. HMM隐马尔科夫模型及MATLAB实现
  7. 【16】 数学建模 | 蒙特卡洛模拟方法 | 详细案例和代码解析(清风课程,有版权问题,私聊删除)
  8. 计算机控制实验室装置,自控/计控原理实验箱 实验仪 实验装置 教学实训设备...
  9. 鸟哥linux命令小结
  10. 阿里达摩院做AI这两年
  11. .NET 2.0 调用FFMPEG
  12. KeyShot中的阴影效果该怎么制作
  13. 奇安信Java后端一面
  14. Plant Simulation中的“开机自启”-autoexec
  15. CentOS 安装Kerberos服务
  16. ue4风格化材质_ue4商城资源Stylized Terrain Pack of 50 Materials50种材质风格化地形包
  17. 通过QI协议发射和接收的无线充需要做CE认证吗?RED指令?
  18. sen1.2词典制作
  19. Python机器学习13——主成分分析
  20. 总结 启用凭证分割后 往来科目 应收 应付 的利润中心处理

热门文章

  1. Bundle的Parcel化处理
  2. oracle19c只使用pdb模式,oracle 19c CDB vs pdb 创建
  3. Linux操作系统实验:生产者和消费者问题
  4. Core Spec 5.0 学习
  5. 免费装Office2021工具Office Tool Plus使用教程
  6. 思迅食通天6单店升级连锁流程
  7. 思科网络模拟器安装与使用
  8. 黎明热血永恒服务器维护,黎明热血永恒暗黑魔幻奇迹觉醒
  9. 解读领跑全国的区块链发展“北京方案”:设专项基金,构建开源生态
  10. InfoQ网站作者的文章列表文章详情获取-Java网络爬虫系统性学习与实战系列(13)