为什么80%的码农都做不了架构师?>>>   

webdriver chrome国内下载地址

http://npm.taobao.org/mirrors/chromedriver/

禁止图片加载

设置参数禁用

// 禁用图片加载
HashMap<String, Object> images = new HashMap();
images.put("images", 2);
HashMap<String, Object> prefs = new HashMap();
prefs.put("profile.default_content_setting_values", images);
options.setExperimentalOption("prefs", prefs);

有效果

利用chrome插件

ChromeOptions op = new ChromeOptions();op.addExtensions(new File("C:\\whatever\\Block-image_v1.0.crx"));driver = new ChromeDriver(op);

参考网址 未尝试,效果未知

无法输入数字1的问题

问题现象与 https://stackoverflow.com/questions/47248275/chrome-webdriver-send-keys-does-not-send-3 这个的现象一致,表现为遇到数字1,则1和之后的字符都无法输入了,但是前面的是不受影响。

  • 它的一个解决办法 send_keys(Keys.NUMPAD3)在我这里是没效果
  • 它的第二个解决办法执行script,可以用 https://stackoverflow.com/questions/48669121/selenium-webdriver-entered-value-for-input-field-was-cut-for-some-unknown-reaso 这里的形式写,更符合代码逻辑。测试通过,而且中文也是支持的。
import org.openqa.selenium.JavascriptExecutor;String script = "arguments[0].value=arguments[1]";
WebElement passwordBox = driver.findElement(By.name("Password"));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript(script, passwordBox, user.password); // 这里arguments[0]就是passwordBox,arguments[1]就是user.password// send a space or TAB to trigger key event
passwordBox.sendKeys(" ");
// passwordBox.sendKeys(Key.TAB);

PS,测试环境为

  • 阿里云CentOS Linux release 7.5.1804 (Core),google-chrome-stable.x86_64 74.0.3729.169-1,74版本的webdriver。无法输入1
  • 阿里云CentOS Linux release 7.5.1804 (Core),google-chrome-stable.x86_64 71,71版本的webdriver。无法输入1
  • 虚拟机CentOS Linux release 7.5.1804,google-chrome-stable.x86_64 74.0.3729.157-1,74版本的webdriver。无法输入1

headless问题

当在服务器上运行不带headless的图形化浏览器时,用xmanager的xshell连接,就能在xmanager里打开那个浏览器,弹出来的桌面选项好像要选 "virtural window" 这个选项。这个有助于服务器的可视化错误调试。

webDriver 防检测的方式

据说通过webDriver访问网站的时候,会使用一些特殊的js变量,正常的访问下,这些变量是没有值的,但是通过webdriver访问,这些变量是有值的,网站也就认为是通过webdriver进行访问的。这里我没进行特别具体的尝试。

通过修改源码方式

  • 可以通过检出源码的方式,把一些变量的名字全修改掉,重新编译。我没试过。
  • 使用vim直接修改打包好的webdriver文件(vim功能真是强大!) 下面这篇文章提到了vim修改内置变量名的方法,但是没试过是否有效。 https://stackoverflow.com/questions/33225947/can-a-website-detect-when-you-are-using-selenium-with-chromedriver

通过开启开发者模式(这个是测试过有效果的)

这篇文章提到了开启浏览器的开发者模式,绕过携程的webdriver检测机制,我测试了的确是有效果的,原先浏览器会显示“目前通过自动化软件进行控制”,开启了开发者模式之后,就没有这个提示了,现在右上角会有“在开发者模式下运行插件不安全”的提示。 https://blog.csdn.net/weixin_43582101/article/details/90416944

原文是python的代码,下面给出java的代码。

ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("excludeSwitches", new String[]{"enable-automation"});

PS: edit at 2019-06-03 这个开发者模式好像不能在headless模式下运行。

搜狗微信尝试

  • 代理尝试的时候,如果出现这样的图片 https://weixin.sogou.com/weixin?type=1&s_from=input&query=%E8%A1%A2%E5%B7%9E%E6%96%87%E6%97%85&ie=utf8&sug=n&sug_type= 这种验证码是访问这样页面会出来的,如果没出来多刷新几次就会出来了

即使手动输入验证码也是没有效果了

输入验证码后的效果

情况一: 405 Not Allowed nginx

情况二: 不管怎么输入验证码还是在这个页面,但是验证码内容变了,这样就还是不行。

情况三: 只有在这种情况下,输入验证码后就正常了,IP也被解封了

  • 如果出现这样的验证码 这种是具体的公众号文章列表页,多刷新几次就会出来了

这个输入验证码后就能继续使用了,而且这个ip也会被解封了

代理ip信息

说明,HTTPS的代理不能给HTTP的使用。

名称 类型 费用 说明
站大爷 http
快代理 http
代理云 未知 合租版 100一天,3000一个月,独享版1500一个月
xici代理/西瓜代理 http/https 个人版9每天,98月,专业版19天,198月,企业版49天,498月 只能筛选出https,无法筛选出http
神鸡代理 http/https 个人版147每个月,专业版228每个月
89免费代理 HTTP
旗云代理 http/https 开放代理6天,30周,80月,399年,私密代理 39天,199周,699月,5999年 暂时测试这个吧,测试过之后发现基本上没办法使用,全部代理IP都会出验证码

只测试了旗云,无效,所有代理IP都出验证码,但是觉得神鸡代理可能效果会好点(因为免费的账号的质量比较好,基本上都能联通,出验证码的,手动输入下这个IP也能用了,但是只有按月收费的,所以没测试)

验证码自动识别尝试(暂时失败)

验证码以搜狗的验证码为例,搜狗有两种验证码,一种是数字 + 英文,一般在搜索的页面出来,另一种纯英文的是具体的文章页面。

安装 tesserocr 和 tesseract

tesseract 是google开源的Ocr的一个库 tesserocr 则是在tesseract的Python操作包

安装方式

安装conda

tesseract里面用Pip 无法安装tesserocr ,需要先装conda,用conda来安装。

Linux安装方式

windows的比较简单,直接 https://docs.conda.io/en/latest/miniconda.html 找到windows的安装就行,然后运行

PS:这篇文章提到了手动下载字库的方法,http://github.com/tesseract-ocr/tessdata ,但是只有基于4.0.0的训练数据,没有我现在装的5.0.0的

运行识别代码

运行下面的代码,注意,由于tesserocr和 pillow都是在conda里面安装的,这里要在 Anaconda Powershell Prompt 打开python

import tesserocr
from PIL import Image
image=Image.open(r'C:\Users\whl\Desktop\验证码\1.jpg')
print(tesserocr.image_to_text(image))
  • 报错1 PIL找不到 这里原生的PIL是没有python3.7版本的,要按照pillow才行。前面用了conda安装了tesserocr,所以这里也只能用conda安装pillow, 运行命令conda install pillow 其他安装方式参照 https://www.cnblogs.com/pcat/p/6790058.html

  • 报错2,没解决 RuntimeError: Failed to init API, possibly an invalid tessdata path: C:\ProgramData\Miniconda3\ 尝试1 失败:添加TESSDATA_PREFIX环境变量为Tesseract-OCR路径,参考 https://blog.csdn.net/l_longqihang/article/details/80621597 文章底下的评论1,报错路径的确变成了新的TESSDATA_PREFIX配置的路径,但是还是一样的错误 尝试2 失败:将尝试1中的tessdata文件夹直接复制到报错的C:\ProgramData\Miniconda3\路径下,还是不行。

验证码自动识别尝试2(使用了尝试3之后已经成功)

由于上面的conda方式失败了,这里使用pip3来装一下试试 参考这篇文章处理 http://www.mamicode.com/info-detail-2353336.html

PIL还是要用下面命令安装扩展版的pillow pip3 install pillow

  • 报错1 ERROR: tesserocr-2.4.0-cp37-cp37m-win_amd64.whl is not a supported wheel on this platform. 这个是我的python版本是32位的,所以tesserocr也要选择32位的python32位版本

  • 报错2 RuntimeError: Failed to init API, possibly an invalid tessdata path: D:\Program Files\Tesseract-OCR/ 还是一样的错,这次甚至路径都是对了,还是失败了

验证码自动识别尝试3(其实是在尝试2的基础上改的)

https://www.imooc.com/article/45278 这里只用到了文章中的一点,就是把tessdata拷贝到 C:\Python36\ !!!! 竟然是放到python的根目录,而不是报错的目录!!!! 我这边的Python安装路径是C:\Users\whl\AppData\Local\Programs\Python\Python37-32,放到这个目录下果然就好了。

这样尝试2利用PIP的方式就是好了的。 尝试1还是不行,但是有篇文章说也是放到了C:\\Miniconda3这样的一个目录,文章暂时找不到了,也不尝试了。

PS:这篇文章里说到语言包,还是有用的

验证码自动识别尝试4(未进行)

还没尝试,前面的尝试已经可以了,就暂时先测试准确率了。 https://blog.csdn.net/qq_18402475/article/details/80347203 再来,这次用JAVA的这篇文章再试试

搜狗验证码识别的准确率测试

先用 https://mp.weixin.qq.com/mp/verifycode?cert=1559036330018.0938 这个网址访问,可以得到一批搜狗的验证码。

#!/bin/bashfor((i=1;i<=10;i++));
do
wget http://mp.weixin.qq.com/mp/verifycode?cert=1559012250995.9602 -O ./verifycode/$i.jpg
done

用这个脚本下载若干个验证码,然后还是用下面的脚本进行识别,基本上不能用!没有一个对的,有些甚至识别不出来

import tesserocr
from PIL import Image
image=Image.open(r'C:\Users\whl\Desktop\验证码\1.jpg')
print(tesserocr.image_to_text(image))

进行手工的训练

https://blog.csdn.net/sylsjane/article/details/83751297 https://blog.csdn.net/a745233700/article/details/80175883 https://www.cnblogs.com/cnlian/p/5765871.html https://www.jianshu.com/p/5c8c6b170f6f (这篇文章最详细,还讲解了识别不全的处理办法) 用这些文章的方法进行训练。

训练好的数据,进行测试 tesseract test.PNG test -l zwp 注意,这里的-l 需要指定新训练的训练集的名字,否则会默认用eng。PS:python的代码没有进行测试,懒得找跟-l zwp等价的python api了。

测试结果显示,只有一个是对的,而且还是训练出有结果的那个。

打码平台测试

这里测试了 http://www.fateadm.com/ 斐斐打码平台。测试效果很理想,测试了10个都是对的(这里测试的是纯英文的那种验证码),10块钱对应1W分,10分可以进行一次识别,换算过来就是一分钱识别一次,算是比较划算的。ps:如果是6位英文 + 数字的要15积分一次,也就是1.5分钱一次。

另外它的API需要上传图片的string数据,可以用下面的JAVA代码对图片进行string的转换

/*** 字符串转图片** @param imgStr   --->图片字符串* @param filename --->图片名* @return*/public static boolean generateImage(String imgStr, String filename) {if (imgStr == null) {return false;}BASE64Decoder decoder = new BASE64Decoder();try {// 解密byte[] b = decoder.decodeBuffer(imgStr);// 处理数据for (int i = 0; i < b.length; ++i) {if (b[i] < 0) {b[i] += 256;}}OutputStream out = new FileOutputStream("D:/Systems/" + filename);out.write(b);out.flush();out.close();return true;} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return false;}/*** 图片转字符串** @param filePath --->文件路径* @return*/public static String getImageStr(String filePath) {InputStream inputStream = null;byte[] data = null;try {inputStream = new FileInputStream(filePath);data = new byte[inputStream.available()];inputStream.read(data);inputStream.close();} catch (IOException e) {e.printStackTrace();}// 加密BASE64Encoder encoder = new BASE64Encoder();return encoder.encode(data);}/** 测试代码*/public static void main(String[] args) {String imageStr = getImageStr("C:\\Users\\whl\\Desktop\\verifycode\\1.jpg");System.out.println(imageStr);boolean generateImage = generateImage(imageStr, "001.jpg");System.out.println(generateImage);}

验证码获取

如果是文章列表页的纯英文的验证码,是访问http://mp.weixin.qq.com/mp/verifycode?cert=1559040332692.3264 这样的Url生成一个全新的验证码图片,同时在cookie里记录下当前图片对应的sig,点提交的时候把sig和正确的验证码校验的。 但是公众号的首页的英文 + 数字的验证码,这个没有仔细研究,因为这两种验证码都没办法直接在页面上进行获取了。

尝试使用webDriver的截图功能实现,下面这篇文章正是利用了这个思路。 https://www.cnblogs.com/lvye001/p/9873796.html

保存验证码的关键代码

                 web = webdriver.Chrome()web.maximize_window()  #页面最大化web.get(list_response.url) #请求验证码页面web.save_screenshot("D:\\quan.png")#截取全屏并保存到该路径imgs = web.find_element_by_id('verify_img') #验证码页面定位验证码图片元素位置#第一步取参数place = imgs.location  #验证码的坐标位置size = imgs.size    #验证码的大小#第二部整理参数(数据为元组)rangle = (int(place['x']), int(place['y']), int(place['x'] + size['width']),int(place['y'] + size['height']))  # 写成我们需要截取的位置坐标#第三步导入PIL,打开截图i = Image.open("D:\\quan.png")#第四部进行抠图操作frame4 = i.crop(rangle)  # 使用Image的crop函数,从截图中再次截取我们需要的区域#第五步 保存抠下来的验证码frame4.save('D:\\cropped.png')  # 保存我们接下来的验证码图片 进行打码web.find_element_by_id('input').send_keys(yundama())#调用云打码返回参数并发送到input框time.sleep(1)web.find_element_by_id('bt').click()#点击提交time.sleep(2)web.close() #关闭浏览器

下面是测试过的JAVA代码,可以正确扣下相应的验证码了。

 /*** 测试抠图获取验证码*/@Testpublic void testGetVerifyCodeImg() throws InterruptedException {String verifyCodeUrl = "http://mp.weixin.qq.com/profile?src=3&timestamp=1559040313&ver=1&signature=v55DcSJ3r49YkKB8nu*QTuO5W5nyIf-FFynVF*SspNgXnVkdy3psJyQS8EMRSkDeBJVQW4bCm2fcHJ44C-M0Gw==";String imagePath = "E:\\snapshot.jpg";String verifyImagePath = "E:\\verify.jpg";WebDriver webDriver = null;try {webDriver = webDriverPool.getActiveWebDriver();webDriver.get(verifyCodeUrl);// 窗口最大化webDriver.manage().window().maximize();// 获取当前页面的截图File scrFile = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);// 把图片保存到本地try {FileUtils.copyFile(scrFile, new File(imagePath));} catch (IOException e) {e.printStackTrace();}// 获取图片的elementWebElement verifyElement = webDriver.findElement(By.id("verify_img"));// 获取图片的位置和大小Point point = verifyElement.getLocation();Dimension dimension = verifyElement.getSize();// 截图出验证码try {BufferedImage image = ImageIO.read(new File(imagePath));BufferedImage verifyImage = image.getSubimage(point.x, point.y, dimension.width, dimension.height);ImageIO.write(verifyImage, "jpg", new File(verifyImagePath));} catch (IOException e) {e.printStackTrace();}System.out.println("done");} finally {webDriver.quit();}}

关于搜狗的反爬机制

  1. cookie的校验 例如直接访问 https://weixin.sogou.com/weixin?type=1&s_from=input&query=%E8%A1%A2%E5%B7%9E%E6%96%87%E6%97%85&ie=utf8&sug=n&sug_type= 这样的公众号页面,搜狗是一定会出验证码的。这里是可以通过设置一系列的header 和 cookie的值进行规避的,这个网上有很多文章讲到了,一般是SUV,SUID,SNUID之类的。 我本地用postman测试了设置headers中的User-Agent = Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36 COOKIE中的SUV = 0074178B73C13FEB5A1BC4917B21D967 就可以访问了,但是访问多次仍然会出验证码。

  2. 公众号文章列表页url中的签名值 当从搜索页面点击某个公众号,进入到公众号首页的时候,观察url地址,http://mp.weixin.qq.com/profile?src=3&timestamp=1559039238&ver=1&signature=v55DcSJ3r49YkKB8nuQTuO5W5nyIf-FFynVFSspNgXnVkdy3psJyQS8EMRSkDe823z7J8R8ijw611KOhv*aQ== 里面有个timestamp和signature字段是动态生成的,这也防止了爬虫爬取固定的公众号首页地址。这里的解决办法是用webDriver进行前面的模拟动作,当出现真正的文章页面的时候url就是固定了的。

  3. 验证码的动态生成 这个是比较变态的地方,即使出现了验证码,想要获取这个验证码进行识别也是比较困难的,每次访问的时候都会产生新的图片,即使通过右键 -> 图片另存为保存也是会请求一张新的图片,需要通过webdirver的截图功能进行保存。

  4. 短时高频访问 在短时间内多次爬取,或者页面上连续刷新时,会触发搜狗的封IP机制,这个时候就会需要输入验证码了。输入正确的验证码会解封IP,也可以更换代理IP。

关于搜狗微信爬取的总结

  1. 前期的所有操作必须使用webDriver进行模拟(至少我是这么做的)。
  2. 如果只是需要爬取特定的几个公众号,用https://weixin.sogou.com/weixin?type=1&s_from=input&query=%E8%A1%A2%E5%B7%9E%E6%96%87%E6%97%85&ie=utf8&sug=n&sug_type= 类似这样的带query的网址直接进去就行了,不用从weixin.sogou.com模拟输入进入。
  3. 验证码只能通过webdriver抠图实现,页面上每次获取就变成新的了,就跟当前页面的验证码不一致了。
  4. 在公众号文章的列表页里,那些文章的url可以从页面上获取,而且可以通过httpclient直接访问(这个是不会出验证码了),虽然也会有timestamp和signature参数,但是在过期时间内足够爬虫爬取页面内容了。这里建议用httpclient爬取,如果用webDriver模拟点击的话,效率挺低的。PS:另外这个文章页面上的有些数据可能是ajax动态填充的,httpclient的获取页面源码里可能是没有的,这样就考虑使用webDriver模拟打开获取吧。
  5. 验证码使用斐斐打码,基本上可以识别搜狗数字 +英文的6位验证码和4位纯英文的两种验证码。如果识别不正确的话,就重新刷新页面识别一次。
  6. 效率问题暂时不考虑,至少功能上先实现。

转载于:https://my.oschina.net/OttoWu/blog/3057807

基于搜狗微信的爬虫知识总结相关推荐

  1. 基于搜狗微信爬取微信公众号的文章

    1. 引入模块和函数 from requests_html import HTMLSession from urllib.parse import urlparse, parse_qs import ...

  2. 搜狗微信反爬虫,让自媒体内容更安全

    2023年5月11日,搜狗微信成为最新一家加入反爬虫大军的公司.作为中国最大的社交平台之一,拥有超过2亿活跃用户的搜狗微信,一直以来都在努力保护其平台上的用户账户和信息安全.然而,随着技术越来越先进, ...

  3. 搜狗微信反爬虫机制探讨及应对方法

    最近项目中,由于需要从微信公众号中获取一些文章内容,所以用到了搜狗微信.一旦搜索的次数稍微多一点,就会触发搜狗微信的反爬虫机制,最初是需要加上User-Agent请求头,后来是要求输入验证码,现在输入 ...

  4. 基于搜狗微信搜索获取公众号文章的阅读量及点赞量

    测试日期:2016/11/13 文章url样例(这个链接是有有效期的): http://mp.weixin.qq.com/s?src=3&timestamp=1479004927&ve ...

  5. php 获取搜狗微信 sn,记搜狗微信号搜索反爬虫

    反爬虫 RSS Factory前段时间又出问题了,访问微信公众号RSS一直500,完全没法用了. 经调试,发现由于爬取数据太频繁,触发了搜狗微信公众号的反爬虫,探索了下反爬虫的规则: 没有带Cooki ...

  6. 九 web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号—抓包软件安装Fiddler4讲解...

    封装模块 #!/usr/bin/env python # -*- coding: utf-8 -*- import urllib from urllib import request import j ...

  7. 微信公众号、微信号、微信文章爬虫(搜狗搜索)

    微信公众号.微信号.微信文章爬虫(搜狗搜索) 微信上面的东西真的不好爬,幸好我找到了一个神器!!! 这个能不能弄点东西出来呢? 这个链接还挺整齐的 嗯哼~~~~~~我似乎发现了什么 直接上代码啦 im ...

  8. python爬虫微信_搜狗微信采集 —— python爬虫系列一

    前言:一觉睡醒,发现原有的搜狗微信爬虫失效了,网上查找一翻发现10月29日搜狗微信改版了,无法通过搜索公众号名字获取对应文章了,不过通过搜索主题获取对应文章还是可以的,问题不大,开搞! 目的:获取搜狗 ...

  9. 基于Jsoup实现搜狗微信搜索文章获取链接、搜索公众号信息、微信登录以及登出

    2020-03-20更新 已上传至GitHub:https://github.com/Aquarius-Seven/demo-jsoup.git,相比CSDN资源,CommonUtil增加了一个处理需 ...

最新文章

  1. c#中的模态对话框和非模态对话框
  2. python chrome headless_Chrome Headless模式(二)——Python+selenium+headerless
  3. Android Binder ProcessState IPCThreadState相关介绍
  4. html diy文本几秒后关闭,利用HTML优化加快网页速度
  5. 单用户修改root密码--centos6.2
  6. xamppmysql访问被拒绝_XAMPP中无法开始MySQL的问题
  7. ACM金牌学长,算法竞赛经验分享
  8. 估计理论(5):BLUE的定义(6.3)
  9. 软件开发中的EJB是什么?
  10. 如何修改dns服务器ip,如何修改DNS服务器IP地址
  11. 澳大利亚维多利亚州旅游局力推高尔夫主题体验
  12. Costech A17M23SWB MTo
  13. linux配置mac地址命令是什么,Linux环境下如何配置IP地址、MAC地址
  14. 手机电视的概念及其发展状况
  15. 【AVL树】AVL树的插入操作以及旋转
  16. fatal: No url found for submodule path ‘xxx‘ in .gitmodule
  17. 【Android 系统开发】 编译 Android文件系统 u-boot 内核 并烧写到 OK-6410A 开发板上
  18. 优化版GM后台包站系统+码支付/代理/84个GM游戏
  19. vue-cli3.x创建项目失败
  20. 【数据结构】时间复杂度_空间复杂度

热门文章

  1. 前端实现小型打包工具
  2. 【译】Jep文档(4)——数据类型(Data Type)
  3. Tomcat重启脚本
  4. 直流马达驱动_ADC_PWM加减速(STM32F4 CubeMX)
  5. 【C/C++】多维向量vector
  6. PDN仿真笔记5-电容走线影响寄生电感的因素分析
  7. 如何向icloud上传文件_怎么把文件放进苹果icloud
  8. nmap——端口扫描_基础命令
  9. List集合去重方法
  10. 【奇怪知识点】百事有雪碧吗?