項目地址
https://github.com/ishare20/JobInformation
思路:
- 明確需要爬取的信息
- 分析網(wǎng)頁結(jié)構(gòu)
- 分析爬取流程
- 優(yōu)化
明確需要爬取的信息
職位名稱
工資
職位描述
公司名稱
公司主頁
詳情網(wǎng)頁
分析網(wǎng)頁結(jié)構(gòu)
目標網(wǎng)站 拉勾網(wǎng)
網(wǎng)站使用json作為交互數(shù)據(jù)咆贬,分析json數(shù)據(jù)灌砖,需要的json關(guān)鍵數(shù)據(jù)
totalCount :查詢總數(shù)嚼摩,用來算頁數(shù),每個頁面顯示15條搀菩,總數(shù)/15得到頁數(shù),大于30只能顯示30頁
positionId :位置id芹缔,用來進入詳情頁秋度,詳情頁網(wǎng)址結(jié)構(gòu)為https://www.lagou.com/jobs/positionId.html
詳情頁網(wǎng)頁分析:查看需要的信息所在的位置,使用Jsoup來解析網(wǎng)頁
分析爬取流程
1.獲取所有的positionId生成詳情頁惯疙,存放在一個存放網(wǎng)址列表中List<String> joburls
2.獲取每個詳情頁并解析為Job類翠勉,得到一個存放Job類的列表List<Job> jobList
3.把List<Job> jobList存進Excel表格中
Java操作Excel需要用到j(luò)xl
關(guān)鍵代碼實現(xiàn)
public List<String> getJobUrls(String gj,String city,String kd){
String pre_url="https://www.lagou.com/jobs/";
String end_url=".html";
String url;
if (gj.equals("")){
url="http://www.lagou.com/jobs/positionAjax.json?px=default&city="+city+"&needAddtionalResult=false&first=false&pn="+pn+"&kd="+kd;
}else {
url="https://www.lagou.com/jobs/positionAjax.json?gj="+gj+"&px=default&city="+city+"&needAddtionalResult=false&first=false&pn="+pn+"&kd="+kd;
}
String rs=getJson(url);
System.out.println(rs);
int total= JsonPath.read(rs,"$.content.positionResult.totalCount");//獲取總數(shù)
int pagesize=total/15;
if (pagesize>=30){
pagesize=30;
}
System.out.println(total);
// System.out.println(rs);
List<Integer> posid=JsonPath.read(rs,"$.content.positionResult.result[*].positionId");//獲取網(wǎng)頁id
for (int j=1;j<=pagesize;j++){ //獲取所有的網(wǎng)頁id
pn++; //更新頁數(shù)
url="https://www.lagou.com/jobs/positionAjax.json?gj="+gj+"&px=default&city="+city+"&needAddtionalResult=false&first=false&pn="+pn+"&kd="+kd;
String rs2=getJson(url);
List<Integer> posid2=JsonPath.read(rs2,"$.content.positionResult.result[*].positionId");
posid.addAll(posid2); //添加解析的id到第一個list
}
List<String> joburls=new ArrayList<>();
//生成網(wǎng)頁列表
for (int id:posid){
String url3=pre_url+id+end_url;
joburls.add(url3);
}
return joburls;
}
public Job getJob(String url){ //獲取工作信息
Job job=new Job();
Document document= null;
document = Jsoup.parse(getJson(url));
job.setJobname(document.select(".name").text());
job.setSalary(document.select(".salary").text());
String joball=HtmlTool.tag(document.select(".job_bt").select("div").html());//清除html標簽
job.setJobdesc(joball);//職位描述包含要求
job.setCompany(document.select(".b2").attr("alt"));
Elements elements=document.select(".c_feature");
//System.out.println(document.select(".name").text());
job.setCompanysite(elements.select("a").attr("href")); //獲取公司主頁
job.setJobdsite(url);
return job;
}
void insertExcel(List<Job> jobList) throws IOException, BiffException, WriteException {
int row=1;
Workbook wb = Workbook.getWorkbook(new File(JobCondition.filename));
WritableWorkbook book = Workbook.createWorkbook(new File(JobCondition.filename), wb);
WritableSheet sheet=book.getSheet(0);
for (int i=0;i<jobList.size();i++){ //遍歷工作列表,一行行插入到表格中
sheet.addCell(new Label(0,row,jobList.get(i).getJobname()));
sheet.addCell(new Label(1,row,jobList.get(i).getSalary()));
sheet.addCell(new Label(2,row,jobList.get(i).getJobdesc()));
sheet.addCell(new Label(3,row,jobList.get(i).getCompany()));
sheet.addCell(new Label(4,row,jobList.get(i).getCompanysite()));
sheet.addCell(new Label(5,row,jobList.get(i).getJobdsite()));
row++;
}
book.write();
book.close();
}
優(yōu)化
在爬取比較多數(shù)據(jù)的時候霉颠,很慢对碌,分析整個流程:
從網(wǎng)址詳情頁列表List<String> joburls中獲取第一個網(wǎng)址————>獲取網(wǎng)頁并解析————>添加到工作列表List<Job> jobList中;
從網(wǎng)址詳情頁列表List<String> joburls中獲取第二個網(wǎng)址————>獲取網(wǎng)頁并解析————>添加到工作列表List<Job> jobList中;
......循環(huán)到網(wǎng)頁列表結(jié)束,每次執(zhí)行都需要等待前一個執(zhí)行完才可以重新發(fā)起請求獲取網(wǎng)頁蒿偎,這時可以使用多線程來優(yōu)化朽们,開啟多線程獲取網(wǎng)頁,主線程等下獲取網(wǎng)頁的子線程結(jié)束后诉位,再執(zhí)行寫入Excel表格操作骑脱。
遇到的問題
有時候抓取太快,直接返回錯誤信息
抓取次數(shù)太多苍糠,被禁止訪問叁丧,隔了一段時間才可以
網(wǎng)站有反爬蟲機制
忘了一個重要的問題,還要分析這些數(shù)據(jù)
參考資料:
https://jsoup.org/
http://www.cnblogs.com/raymond19840709/archive/2008/06/26/1230289.html
https://github.com/json-path/JsonPath