用selenium打开加载了自己写的chrome扩展的一个浏览器,其中响应头修改失效了,在正常开发启动的浏览器中没有发现这个问题,请问哪位大佬遇到过这种情况,该如何解决,修改响应头回调代码如下:fun...
用selenium打开加载了自己写的chrome扩展的一个浏览器,其中响应头修改失效了,在正常开发启动的浏览器中没有发现这个问题,请问哪位大佬遇到过这种情况,该如何解决,修改响应头回调代码如下:
function callback(requestDetails) {
requestDetails.responseHeaders.forEach(header => {
if (header.name == 'Content-Type' && header.value == "text/plain") {
header.value = header.value + ";charset=UTF-8";
}});
return {responseHeaders: requestDetails.responseHeaders};
}
先看浏览器开发工具下,请求包是否修改了头
直接使用抓包工具,如wireshark,抓下这个端口的网络包,这是最终的网络传输包,如果修改了肯定就是修改了,而且可以看到传递的真实数据流
前言
本文利用selenium、百度OCR在线文字识别完成某一网站的模拟登陆操作,通过OCR识别验证码完成登陆后返回cookie,常用于Java爬虫。
准备工作
在百度智能云官网创建OCR图像识别项目,获取项目的APIKey以及SecretKey下载百度OCR需要用到的工具类下载chromedriver.exe驱动
OCR项目创建
注册登录百度智能云账号,网址:https://login.bce.baidu.com/选择文字识别功能并且完成应用创建应用创建完毕后点击管理应用,获取项目的APIKey以及SecretKey这里选用网络图片文字识别,和通用文字识别相比识别率会更高,对应api学习网址https://cloud.baidu.com/doc/OCR/s/Sk3h7xyad
对应Util工具类的下载(5个)
*https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
*https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2
*https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
*https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
*第五个手动添加,如下
importorg.json.JSONObject;
importjava.io.BufferedReader;
importjava.io.InputStreamReader;
importjava.net.HttpURLConnection;
importjava.net.URL;
importjava.util.List;
importjava.util.Map;
/**
*获取token类
*/
publicclassAuthService{
/**
*获取权限token
*@return返回示例:
*{
*"access_token":"24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567",
*"expires_in":2592000
*}
*/
publicstaticStringgetAuth(){
//官网获取的APIKey更新为你注册的
StringclientId="百度云应用的AK";
//官网获取的SecretKey更新为你注册的
StringclientSecret="百度云应用的SK";
returngetAuth(clientId,clientSecret);
}
/**
*获取API访问token
*该token有一定的有效期,需要自行管理,当失效时需重新获取.
*@paramak-百度云官网获取的APIKey
*@paramsk-百度云官网获取的SecuretKey
*@returnassess_token示例:
*"24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"
*/
publicstaticStringgetAuth(Stringak,Stringsk){
//获取token地址
StringauthHost="https://aip.baidubce.com/oauth/2.0/token?";
StringgetAccessTokenUrl=authHost
//1.grant_type为固定参数
+"grant_type=client_credentials"
//2.官网获取的APIKey
+"&client_id="+ak
//3.官网获取的SecretKey
+"&client_secret="+sk;
try{
URLrealUrl=newURL(getAccessTokenUrl);
//打开和URL之间的连接
HttpURLConnectionconnection=(HttpURLConnection)realUrl.openConnection();
connection.setRequestMethod("GET");
connection.connect();
//获取所有响应头字段
Map>map=connection.getHeaderFields();
//遍历所有的响应头字段
for(Stringkey:map.keySet()){
System.err.println(key+"--->"+map.get(key));
}
//定义BufferedReader输入流来读取URL的响应
BufferedReaderin=newBufferedReader(newInputStreamReader(connection.getInputStream()));
Stringresult="";
Stringline;
while((line=in.readLine())!=null){
result+=line;
}
/**
*返回结果示例
*/
System.err.println("result:"+result);
JSONObjectjsonObject=newJSONObject(result);
Stringaccess_token=jsonObject.getString("access_token");
returnaccess_token;
}catch(Exceptione){
System.err.printf("获取token失败!");
e.printStackTrace(System.err);
}
returnnull;
}
}
下载Chromedriver.exe插件
首先查看自己谷歌浏览器的版本,地址栏输入chrome://version/浏览器版本号与驱动版本对应关系下载地址https://npm.taobao.org/mirrors/chromedriver/其他版本对应关系
chromedriver版本支持的chrome版本v2.46v72-74v2.45v70-72v2.44v69-71v2.43v69-71v2.42v68-70v2.41v67-69v2.40v66-68v2.39v66-68v2.38v65-67v2.37v64-66v2.36v63-65v2.35v62-64v2.34v61-63v2.33v60-62v2.32v59-61v2.31v58-60v2.30v58-60v2.29v56-58v2.28v55-57v2.27v54-56v2.26v53-55v2.25v53-55v2.24v52-54v2.23v51-63v2.22v49-52v2.21v46-50v2.20v43-48v2.19v43-47v2.18v43-42v2.17v42-43v2.16v42-45v2.15v40-43v2.14v39-42v2.13v38-41v2.12v36-40v2.11v36-40v2.10v33-36v2.9v31-34
ps:下载完毕后把chromedriver.exe放置在运行工程的根目录下
代码编写
依赖导入
百度OCR验证码识别类
/**
*@Author:zf
*@Date:2020/08/2609:08:35
*@Desc:调用百度OCR接口来识别验证码,直接返回识别后得到的字符串内容
*/
publicclassBaiDuOcr{
//传入参数为图片的本地地址
publicstaticStringwebImage(StringimageUrl){
//请求url
Stringurl="https://aip.baidubce.com/rest/2.0/ocr/v1/webimage";
//识别得到的字串
Stringresult=null;
try{
//本地文件路径
StringfilePath=imageUrl;
byte[]imgData=FileUtil.readFileByBytes(filePath);
StringimgStr=Base64Util.encode(imgData);
StringimgParam=URLEncoder.encode(imgStr,"UTF-8");
Stringparam="image="+imgParam;
//获取百度Ocrtoken
StringaccessToken=AuthService.getAuth(APIKey,SecretKey);
result=HttpUtil.post(url,accessToken,param);
result=result.substring(result.lastIndexOf(":")+3,result.lastIndexOf("\""));
}catch(Exceptione){
e.printStackTrace();
}
returnresult;
}
}
模拟登陆类
importorg.apache.commons.io.FileUtils;
importorg.openqa.selenium.*;
importorg.openqa.selenium.chrome.ChromeDriver;
importorg.openqa.selenium.chrome.ChromeOptions;
importjavax.imageio.ImageIO;
importjava.awt.image.BufferedImage;
importjava.io.File;
importjava.io.IOException;
importjava.util.regex.Matcher;
importjava.util.regex.Pattern;
/**
*@Author:zf
*@Date:2020/08/2611:38:06
*@Desc:采用selenium+百度OCR,通过截取网页上的验证码图片发送至百度OCR处理后完成登录操作,并且返回对应的cookie
*/
publicclassCookieLogin{
privatestaticStringcookies=null;
/*
*参数说明:
*url:请求地址url
*nameId:用户名输入框所在标签的id
*pwdId:密码输入框所在标签的id
*imageId:验证码图片所在标签的id
*codeId:验证码输入框所在标签的id
*loginClass:登录按钮所在标签的class
*name:用户名
*pwd:密码
**/
publicstaticStringdoLogin(Stringurl,StringnameId,StringpwdId,StringimageId,StringcodeId,
StringloginClass,Stringname,Stringpwd){
System.getProperties().setProperty("webDriver.chrome.dirver","chromedriver.exe");
//启动模拟浏览器
ChromeOptionschromeOptions=newChromeOptions();
chromeOptions.setHeadless(true);
WebDriverdriver=newChromeDriver(chromeOptions);
driver.get(url);
driver.manage().window().maximize();
//定义验证码变量
Stringverify=null;
//寻找账号编辑框
driver.findElement(By.id(nameId)).clear();
driver.findElement(By.id(nameId)).sendKeys(name);
//寻找密码编辑框
driver.findElement(By.id(pwdId)).clear();
driver.findElement(By.id(pwdId)).sendKeys(pwd);
//创建一个时间戳,防止验证码图片文件重名
Stringtimestamp=System.currentTimeMillis()+"";
//寻找验证码容器
WebElementele=driver.findElement(By.id(imageId));
//创建一个快照
Filescreenshot=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
//读取截图
BufferedImagefullImg=null;
try{
fullImg=ImageIO.read(screenshot);
//获取页面上元素的位置
org.openqa.selenium.Pointpoint=ele.getLocation();
//获取元素宽高
inteleWidth=ele.getSize().getWidth();
inteleHeight=ele.getSize().getHeight();
//计算比例
floatrate=(float)fullImg.getWidth()/1280;
//裁剪整个页面截图只得到元素截图
BufferedImageeleScreenshot=fullImg.getSubimage((int)(point.getX()*rate),
(int)(point.getY()*rate),
(int)(eleWidth*rate),
(int)(eleHeight*rate));
ImageIO.write(eleScreenshot,"png",screenshot);
//将验证码截图保存到本地
FilescreenshotLocation=newFile(timestamp+".jpg");
FileUtils.copyFile(screenshot,screenshotLocation);
//调用百度OCR
StringfilePath=timestamp+".jpg";
Stringresult=BaiDuOcr.webImage(filePath);
//删除本地文件
screenshotLocation.delete();
//寻找验证码编辑框
driver.findElement(By.id(codeId)).clear();
driver.findElement(By.id(codeId)).sendKeys(result);
//模拟点击登录按钮
driver.findElement(By.className(loginClass)).click();
Thread.sleep(5000);
//获取cookie信息
cookies=driver.manage().getCookies().toString();
}catch(IOExceptione){
e.printStackTrace();
}catch(InterruptedExceptione){
e.printStackTrace();
}finally{
driver.quit();
}
returncookies;
}
}
调用类
/**
*@Author:zf
*@Date:2020/08/2722:42:19
*/
publicclassgetCookie{
publicstaticvoidmain(String[]args){
StringCookie=CookieLogin.doLogin(请求地址url,
用户名输入框所在标签的id,
密码输入框所在标签的id,
验证码图片所在标签的id,
"验证码输入框所在标签的id,
登录按钮所在标签的class,
用户名,
密码);
System.out.println(Cookie);
}
}
配置文件
log4j.properties
log4j.rootLogger=INFO,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d%p[%c]-%m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d%p[%c]-%m%n
selenium.properties
#WhatWebDrivertouseforthetests
#driver=phantomjs
#driver=firefox
driver=chrome
#driver=http://localhost:8910
#driver=http://localhost:4444/wd/hub
#PhantomJSspecificconfig(changeaccordingtoyourinstallation)
#phantomjs_exec_path=/Users/Bingo/bin/phantomjs-qt5
#phantomjs_exec_path=d:/phantomjs.exe
#chrome_exec_path=E:\\demo\\crawler\\chromedriver.exe
#phantomjs_driver_path=/Users/Bingo/Documents/workspace/webmagic/webmagic-selenium/src/main.js
#phantomjs_driver_loglevel=DEBUG
chrome_driver_loglevel=DEBUG
总结
最近在学习Java的爬虫,在网络上查找使用selenium进行模拟识别验证码登录后返回cookie的教程非常的少,因此写下这篇教程。此外,在爬虫程序的实际开发中,对于爬虫带验证码登录的情况非常多见,对于验证码比较清晰的情况可以使用教程里的百度OCR或tesseract-ocr工具进行识别,但是对于比较复杂的验证码以及滑块、文字类的复杂验证码,一般会接入打码平台来完成。
相关问题推荐
换行。比如,print hello\nworld效果就是helloworld\n就是一个换行符。\是转义的意思,'\n'是换行,'\t'是tab,'\\'是,\ 是在编写程序中句子太长百,人为换行后加上\但print出来是一整行。...
十种常见排序算法一般分为以下几种:(1)非线性时间比较类排序:a. 交换类排序(快速排序、冒泡排序)b. 插入类排序(简单插入排序、希尔排序)c. 选择类排序(简单选择排序、堆排序)d. 归并排序(二路归并排序、多路归并排序)(2)线性时间非比较类排序:...
前景很好,中国正在产业升级,工业机器人和人工智能方面都会是强烈的热点,而且正好是在3~5年以后的时间。难度,肯定高,要求你有创新的思维能力,高数中的微积分、数列等等必须得非常好,软件编程(基础的应用最广泛的语言:C/C++)必须得很好,微电子(数字电...
迭代器与生成器的区别:(1)生成器:生成器本质上就是一个函数,它记住了上一次返回时在函数体中的位置。对生成器函数的第二次(或第n次)调用,跳转到函数上一次挂起的位置。而且记录了程序执行的上下文。生成器不仅记住了它的数据状态,生成器还记住了程序...
python中title( )属于python中字符串函数,返回’标题化‘的字符串,就是单词的开头为大写,其余为小写
第一种解释:代码中的cnt是count的简称,一种电脑计算机内部的数学函数的名字,在Excel办公软件中计算参数列表中的数字项的个数;在数据库( sq| server或者access )中可以用来统计符合条件的数据条数。函数COUNT在计数时,将把数值型的数字计算进去;但是...
head是方法,所以需要取小括号,即dataset.head()显示的则是前5行。data[:, :-1]和data[:, -1]。另外,如果想通过位置取数据,请使用iloc,即dataset.iloc[:, :-1]和dataset.iloc[:, -1],前者表示的是取所有行,但不包括最后一列的数据,结果是个DataFrame。...
挺简单的,其实课程内容没有我们想象的那么难、像我之前同学,完全零基础,培训了半年,直接出来就工作了,人家还在北京大公司上班,一个月15k,实力老厉害了
Python针对众多的类型,提供了众多的内建函数来处理(内建是相对于导入import来说的,后面学习到包package时,将会介绍),这些内建函数功用在于其往往可对多种类型对象进行类似的操作,即多种类型对象的共有的操作;如果某种操作只对特殊的某一类对象可行,Pyt...
相当于 ... 这里不是注释
还有FIXME
python的两个库:xlrd和xlutils。 xlrd打开excel,但是打开的excel并不能直接写入数据,需要用xlutils主要是复制一份出来,实现后续的写入功能。
单行注释:Python中的单行注释一般是以#开头的,#右边的文字都会被当做解释说明的内容,不会被当做执行的程序。为了保证代码的可读性,一般会在#后面加一两个空格然后在编写解释内容。示例:# 单行注释print(hello world)注释可以放在代码上面也可以放在代...
主要是按行读取,然后就是写出判断逻辑来勘测行是否为注视行,空行,编码行其他的:import linecachefile=open('3_2.txt','r')linecount=len(file.readlines())linecache.getline('3_2.txt',linecount)这样做的过程中发现一个问题,...
或许是里面有没被注释的代码
自学的话要看个人情况,可以先在B站找一下视频看一下