OkHttp可以向指定链接发送请求,然后获得响应,Jsoup可用于解析html,Jsoup强大的地方是Select方法,可以通过传入元素选择表达式来获得元素
谷歌浏览器有个功能可以获得元素选择的表达式
这样就把选择元素的表达式复制到粘贴板了
接下来看代码实现
因为我创建的是maven项目,我们可以再pom文件中添加依赖
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.11.0</version>
</dependency>
然后我对Okhttp封装了一下,可以通过方法来获得String 响应
public class HttpUtil {
static private OkHttpClient okHttpClient;
static {
okHttpClient = new OkHttpClient.Builder().build();
}
public static String getStringResopnce(String url, Map<String, String> paramMap) throws IOException {
String formParam = "?";
if (paramMap != null) {
for (Map.Entry<String, String> entry : paramMap.entrySet()) {
formParam += entry.getKey() + "=" + entry.getValue();
}
}
Request request = new Request.Builder().url(url + formParam).addHeader("user-agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36").build();
return okHttpClient.newCall(request).execute().body().string();
}
}
首先我们定义一个方法接收一个url,可以返回List<Job>
static public List<Job> getJobList(String url)
然后通过工具类来获得String 响应
List<Job> result=new ArrayList<>();
String stringResopnce = HttpUtil.getStringResopnce(url, null);
Document parse = Jsoup.parse(stringResopnce);
List<Element> elements= parse.select("#main > div > div.job-list > ul > li");
并且通过select方法,传入一个元素选择的表达式就能获得所有li了
为什么要获得li呢,还有这个表达式怎么来的
这样来的....
谷歌大佬们整的
右击指定元素右击可以复制元素选择的表达式,然后稍微修改就能获得我们想要的元素了
接下来就要解析每个Element获得里面的数据(右击元素copy selector #[滑稽] )
for(Element e:elements){
Job job=new Job();
//id
String id = e.select("div > div.info-primary > h3 > a").attr("data-jobid");
if(isContaint(id))
continue;
job.setId(id);
//职位名
String jobName = e.select("div.info-primary > h3 > a > div.job-title").text();
job.setJobName(jobName);
//薪酬
String salary = e.select("div > div.info-primary > h3 > a > span").text();
job.setSalary(salary);
//公司名
String companyName = e.select("div > div.info-company > div > h3 > a").text();
job.setCompanyType(companyName);
//公司类型
String companyType = e.select("div > div.info-company > div > p").text();
job.setCompanyType(companyType);
//要求
String yaoqiu = e.select("div > div.info-primary > p").text();
job.setYaoqiu(yaoqiu);
//发布时间
String createTime = e.select("div > div.info-publis > p").text();
job.setCreateTime(createTime);
//谁招聘
String who = e.select("div > div.info-publis > h3").text();
job.setWho(who);
//链接
String href = e.select("div > div.info-primary > h3 > a").attr("href");
job.setLink(href);
System.out.println(job);
result.add(job);
}
然后几乎每个网站都有对爬虫的防护,如果访问频率过高后台会认为你在爬他数据,这里适当休眠下
Thread.currentThread().sleep(5000);
数据是分页显示的,我们在获得一页数据后需要获得下一页的数据
下一页的数据访问链接保存到了一个a 标签里,这里我们获得这个链接然后递归获得数据
String href = parse.select("#main > div > div.job-list > div.page > a.next").attr("href");
if(!href.contains("javascript"))
result.addAll(getJobList("https://www.zhipin.com"+href+"&ka=page-next"));
return result;
方法结束
***注意,这里有个坑,
如果直接用这个地址的话,boss服务器会认为你在用爬虫,后来我把这个链接和浏览器访问的链接进行了对比,发现浏览器比这个链接多了一个参数传递
这个参数叫 ka,值是page-next ,如果不传递这个参数,服务器也会认为你在爬他数据,然后只返回第一页的数据(很坑爹),加了参数就没问题了
以上是爬到的数据
告辞