基于搜狗微信的爬虫知识总结
为什么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×tamp=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();}}
关于搜狗的反爬机制
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 就可以访问了,但是访问多次仍然会出验证码。
公众号文章列表页url中的签名值 当从搜索页面点击某个公众号,进入到公众号首页的时候,观察url地址,http://mp.weixin.qq.com/profile?src=3×tamp=1559039238&ver=1&signature=v55DcSJ3r49YkKB8nuQTuO5W5nyIf-FFynVFSspNgXnVkdy3psJyQS8EMRSkDe823z7J8R8ijw611KOhv*aQ== 里面有个timestamp和signature字段是动态生成的,这也防止了爬虫爬取固定的公众号首页地址。这里的解决办法是用webDriver进行前面的模拟动作,当出现真正的文章页面的时候url就是固定了的。
验证码的动态生成 这个是比较变态的地方,即使出现了验证码,想要获取这个验证码进行识别也是比较困难的,每次访问的时候都会产生新的图片,即使通过右键 -> 图片另存为保存也是会请求一张新的图片,需要通过webdirver的截图功能进行保存。
短时高频访问 在短时间内多次爬取,或者页面上连续刷新时,会触发搜狗的封IP机制,这个时候就会需要输入验证码了。输入正确的验证码会解封IP,也可以更换代理IP。
关于搜狗微信爬取的总结
- 前期的所有操作必须使用webDriver进行模拟(至少我是这么做的)。
- 如果只是需要爬取特定的几个公众号,用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模拟输入进入。
- 验证码只能通过webdriver抠图实现,页面上每次获取就变成新的了,就跟当前页面的验证码不一致了。
- 在公众号文章的列表页里,那些文章的url可以从页面上获取,而且可以通过httpclient直接访问(这个是不会出验证码了),虽然也会有timestamp和signature参数,但是在过期时间内足够爬虫爬取页面内容了。这里建议用httpclient爬取,如果用webDriver模拟点击的话,效率挺低的。PS:另外这个文章页面上的有些数据可能是ajax动态填充的,httpclient的获取页面源码里可能是没有的,这样就考虑使用webDriver模拟打开获取吧。
- 验证码使用斐斐打码,基本上可以识别搜狗数字 +英文的6位验证码和4位纯英文的两种验证码。如果识别不正确的话,就重新刷新页面识别一次。
- 效率问题暂时不考虑,至少功能上先实现。
转载于:https://my.oschina.net/OttoWu/blog/3057807
基于搜狗微信的爬虫知识总结相关推荐
- 基于搜狗微信爬取微信公众号的文章
1. 引入模块和函数 from requests_html import HTMLSession from urllib.parse import urlparse, parse_qs import ...
- 搜狗微信反爬虫,让自媒体内容更安全
2023年5月11日,搜狗微信成为最新一家加入反爬虫大军的公司.作为中国最大的社交平台之一,拥有超过2亿活跃用户的搜狗微信,一直以来都在努力保护其平台上的用户账户和信息安全.然而,随着技术越来越先进, ...
- 搜狗微信反爬虫机制探讨及应对方法
最近项目中,由于需要从微信公众号中获取一些文章内容,所以用到了搜狗微信.一旦搜索的次数稍微多一点,就会触发搜狗微信的反爬虫机制,最初是需要加上User-Agent请求头,后来是要求输入验证码,现在输入 ...
- 基于搜狗微信搜索获取公众号文章的阅读量及点赞量
测试日期:2016/11/13 文章url样例(这个链接是有有效期的): http://mp.weixin.qq.com/s?src=3×tamp=1479004927&ve ...
- php 获取搜狗微信 sn,记搜狗微信号搜索反爬虫
反爬虫 RSS Factory前段时间又出问题了,访问微信公众号RSS一直500,完全没法用了. 经调试,发现由于爬取数据太频繁,触发了搜狗微信公众号的反爬虫,探索了下反爬虫的规则: 没有带Cooki ...
- 九 web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号—抓包软件安装Fiddler4讲解...
封装模块 #!/usr/bin/env python # -*- coding: utf-8 -*- import urllib from urllib import request import j ...
- 微信公众号、微信号、微信文章爬虫(搜狗搜索)
微信公众号.微信号.微信文章爬虫(搜狗搜索) 微信上面的东西真的不好爬,幸好我找到了一个神器!!! 这个能不能弄点东西出来呢? 这个链接还挺整齐的 嗯哼~~~~~~我似乎发现了什么 直接上代码啦 im ...
- python爬虫微信_搜狗微信采集 —— python爬虫系列一
前言:一觉睡醒,发现原有的搜狗微信爬虫失效了,网上查找一翻发现10月29日搜狗微信改版了,无法通过搜索公众号名字获取对应文章了,不过通过搜索主题获取对应文章还是可以的,问题不大,开搞! 目的:获取搜狗 ...
- 基于Jsoup实现搜狗微信搜索文章获取链接、搜索公众号信息、微信登录以及登出
2020-03-20更新 已上传至GitHub:https://github.com/Aquarius-Seven/demo-jsoup.git,相比CSDN资源,CommonUtil增加了一个处理需 ...
最新文章
- c#中的模态对话框和非模态对话框
- python chrome headless_Chrome Headless模式(二)——Python+selenium+headerless
- Android Binder ProcessState IPCThreadState相关介绍
- html diy文本几秒后关闭,利用HTML优化加快网页速度
- 单用户修改root密码--centos6.2
- xamppmysql访问被拒绝_XAMPP中无法开始MySQL的问题
- ACM金牌学长,算法竞赛经验分享
- 估计理论(5):BLUE的定义(6.3)
- 软件开发中的EJB是什么?
- 如何修改dns服务器ip,如何修改DNS服务器IP地址
- 澳大利亚维多利亚州旅游局力推高尔夫主题体验
- Costech A17M23SWB MTo
- linux配置mac地址命令是什么,Linux环境下如何配置IP地址、MAC地址
- 手机电视的概念及其发展状况
- 【AVL树】AVL树的插入操作以及旋转
- fatal: No url found for submodule path ‘xxx‘ in .gitmodule
- 【Android 系统开发】 编译 Android文件系统 u-boot 内核 并烧写到 OK-6410A 开发板上
- 优化版GM后台包站系统+码支付/代理/84个GM游戏
- vue-cli3.x创建项目失败
- 【数据结构】时间复杂度_空间复杂度