最近在过年以及躲避疫情。。。。
汇报一下组一斤的收获吧,其实也不多,但是着实费了很大的力气,我现在正在修生养息阶段,接下来先着手一下其他方面的内容,
首先,关于webmagic的,获取下一页的操作,目前能够成功的是使用Selenium的操作,在几天这个就成功了,但是之后的操作由于缺少函数,我现在还未找到合适的开发手段。
源码:
1 package com.ms.test; 2 3 import org.openqa.selenium.By; 4 import org.openqa.selenium.WebElement; 5 import org.openqa.selenium.chrome.ChromeDriver; 6 7 public class TestSelenium { 8 9 public static void main(String[] args) { 10 // System.setProperty("webdriver.chrome.driver","C:\\Users\\hp\\AppData\\Local\\Google\\Chrome\\Application\\chromedriver.exe"); 11 // 使用webdriver点击翻页按钮,达到获取第二页的内容。 12 ChromeDriver chormDriver = new ChromeDriver(); 13 // 获取页面 14 chormDriver.get("http://www.beijing.gov.cn/hudong/hdjl/com.web.search.mailList.flow"); 15 16 //测试1,获取页面源码 17 //System.out.println(chormDriver.getCurrentUrl()); 18 19 20 //方法1 21 // 点击下一页按钮获取下一页数据 22 //getNextPageByNextButton(chormDriver); 23 24 //方法2 25 int num = 5; 26 // 输入页数获取下一页数据 27 for(int n=1;n<num;n++) { 28 getNextPageByInputNum(chormDriver, num); 29 } 30 31 } 32 33 34 35 private static void getNextPageByInputNum(ChromeDriver chormDriver, int num) { 36 // TODO Auto-generated method stub 37 WebElement textInput = chormDriver.findElement(By.id("pageNum")); 38 // 在输入框输入“num” 39 //将num转为string、类型 40 String strNum= String.valueOf(num); 41 textInput.sendKeys(strNum); 42 // 根据id获取“确定”按钮,"page_text_new"只存在一个,所以可以正常使用 43 WebElement submit = chormDriver.findElement(By.className("page_go_new")); 44 submit.click(); 45 // 等待5秒 46 try { 47 Thread.sleep(2000); 48 String newPage = chormDriver.getPageSource(); 49 chormDriver.findElementByXPath("//div[@class=list-group]/div/a/span/text()"); 50 //System.out.println(newPage); 51 } catch (InterruptedException e) { 52 // TODO Auto-generated catch block 53 e.printStackTrace(); 54 } 55 System.out.println("通过页数得到:"+chormDriver.getPageSource()); 56 } 57 58 59 60 @SuppressWarnings("unused") 61 private static void getNextPageByNextButton(ChromeDriver chormDriver) { 62 // TODO Auto-generated method stub 63 64 WebElement submit = chormDriver.findElement(By.id("nextPage")); 65 submit.click(); 66 // 等待5秒 67 try { 68 Thread.sleep(2000); 69 //String newPage = chormDriver.getPageSource(); 70 //System.out.println(newPage); 71 } catch (InterruptedException e) { 72 // TODO Auto-generated catch block 73 e.printStackTrace(); 74 } 75 //System.out.println("通过下一页按钮得到:"+chormDriver.findElementByCssSelector("div.pb-3 a")); 76 } 77 }View Code
这个比较麻烦的是配置环境,刚开始会报一些错误,如果你没有安装好的话,至于安装教程,给个链接吧:https://www.cnblogs.com/lipo/p/10273054.html
里面比较关键的是jar包与自己浏览器的版本问题,我安装的是chorme的driver:
版本匹配链接:
https://blog.csdn.net/yoyocat915/article/details/80580066
这些环境都准备好了的话,基本代码就没问题了,获取下一页就可以成功了,页面也会获取源码,但是获取的源码是String类型,url是不要想了,每个都一样,
还有一个改良版的下一页按钮问题,我这个呢,不是每次都能成功的,因为网络问题,获取参数到本地是需要时间的,我这里是3秒不到,所以我设置成了3秒
改良版代码:
1 package com.ms.work; 2 3 import org.openqa.selenium.JavascriptExecutor; 4 import org.openqa.selenium.chrome.ChromeDriver; 5 6 7 public class SeleniumForWork { 8 9 10 //执行函数 11 public static void main(String[] args) { 12 //启动ChromeDriver 13 ChromeDriver chromeDriver = new ChromeDriver(); 14 //获取网址 15 chromeDriver.get("http://www.beijing.gov.cn/hudong/hdjl/com.web.search.mailList.flow"); 16 //通过下一页获取网页内容 17 for(int i=1;i<5625;i++) 18 { 19 System.out.println("第"+i+"次:"); 20 getNextPageByNextButton(chromeDriver); 21 22 } 23 } 24 25 private static void getNextPageByNextButton(ChromeDriver chromeDriver) { 26 // TODO Auto-generated method stub 27 //通过js实现页面跳转 28 JavascriptExecutor driver_js=((JavascriptExecutor) chromeDriver); 29 driver_js.executeScript("pageTurning(3);"); 30 //每次等待3秒 31 try { 32 Thread.sleep(3000); 33 } catch (InterruptedException e) { 34 // TODO Auto-generated catch block 35 e.printStackTrace(); 36 } 37 //得到网页源码 38 String pageHtml=chromeDriver.getPageSource(); 39 //pageHtml. 40 } 41 }View Code
这改良就在于直接获取它的js函数并执行这个函数,还有一种方法就是对string类型的页面分析,或者将页面下载下来,在进行分析,我一直在寻找对页面直接处理的方式,但是我还没找到。
在一个就是模拟post方法进行页面信息的回传,这个就需要获取它的json包了,但是我在尝试了n次之后,确定了他对这方面的反扒取对新手是多麽的。。打击大,我到现在只能获取他的假网页,先贴出来吧
post方法源码:
1 package com.ms.test; 2 3 import us.codecraft.webmagic.Page; 4 import us.codecraft.webmagic.Request; 5 import us.codecraft.webmagic.Site; 6 import us.codecraft.webmagic.Spider; 7 import us.codecraft.webmagic.model.HttpRequestBody; 8 import us.codecraft.webmagic.pipeline.FilePipeline; 9 import us.codecraft.webmagic.processor.PageProcessor; 10 import us.codecraft.webmagic.utils.HttpConstant; 11 12 //测试post请求 13 public class PostTest implements PageProcessor { 14 15 private int i=2; 16 Site site = Site.me() 17 .setCharset("utf8") 18 .addHeader("Accept", "application/json, text/javascript, */*; q=0.01") 19 .addHeader("Accept-Encoding", "gzip, deflate") 20 // .addHeader("Content-Length", "154") 21 .addHeader("Content-Type", "text/json") 22 .addHeader("Cookie", 23 "HDJLJSID=CA4836B90F87481FF2F058B1CC55A9DB; COLLCK=450643787; __jsluid_h=ef4b0c26f04e5a1d5f45852c5ca56be8; _gscu_564121711=786606432o71ul19; X-LB=1.1.44.637df82f; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2216fac66039437c-020fb489e91b5b-c383f64-1044480-16fac660395485%22%7D; route=a2cec3cb28b0d59d32db7b39f74f56a5; _va_ses=*; __utrace=2ff9ccfaa6d808ac51b2801d1017a8bd; _va_id=04e0bd362a2b8f01.1578657775.19.1579601861.1579601759.") 24 .addHeader("User-Agent", 25 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"); 26 27 @Override 28 public Site getSite() { 29 // TODO Auto-generated method stub 30 return site; 31 } 32 33 @Override 34 public void process(Page page) { 35 // TODO Auto-generated method stub 36 // 得到信息 37 //page.putField("list", page.getHtml().xpath("//div[@class=list-group]/div/a/span/text()").all()); 38 System.out.println(page.getHtml().toString()); 39 Request request; 40 request = new Request("http://www.beijing.gov.cn/hudong/hdjl/com.web.search.mailList.mailList.biz.ext"); 41 request.setRequestBody(HttpRequestBody.json("{begin:"+ i*6 42 + ",length: 6,count: 33739,totalPage: 5624,currentPage:"+(i+1) 43 + ",isCount: 'true',isFirst: 'false',isLast: 'false',size: 6}", "utf-8")); 44 request.setMethod(HttpConstant.Method.POST); 45 page.addTargetRequest(request); 46 try { 47 Thread.sleep(3000); 48 } catch (InterruptedException e) { 49 // TODO Auto-generated catch block 50 e.printStackTrace(); 51 } 52 i++; 53 } 54 55 // 主函数 56 public static void main(String[] args) { 57 58 Spider.create(new PostTest()).addUrl("http://www.beijing.gov.cn/hudong/hdjl/com.web.search.mailList.flow") // 设置要抓取的页面 59 .thread(5) 60 //.addPipeline(new FilePipeline("C:\\Users\\hp\\Desktop\\数据\\result3")) 61 .run(); 62 63 } 64 }View Code
这个只能获取假的,你输出网页信息就知道了,
这里有一个成功案例,
成功案例源码:
1 package com.ms.test; 2 3 import java.util.List; 4 import us.codecraft.webmagic.Page; 5 import us.codecraft.webmagic.Request; 6 import us.codecraft.webmagic.Site; 7 import us.codecraft.webmagic.Spider; 8 import us.codecraft.webmagic.model.HttpRequestBody; 9 import us.codecraft.webmagic.processor.PageProcessor; 10 import us.codecraft.webmagic.utils.HttpConstant; 11 12 /** 13 * 抓取博客园上的所有文章(一) 14 * 模拟POST请求 15 * 步骤: 16 * 1. F12查看源码,从网络查看实际请求地址,以及参数 17 * 2. 判断当前页面是否为主界面,若为主界面,将当前界面的链接添加到抓取列表 18 * 并模拟POST请求。 19 * 3. 若当前请求链接与实际链接相匹配,且请求的页码在范围内,用List 将链接 20 * 储存下来,并添加到抓取列表。模拟POST请求,将请求的页码的界面的所有 21 * 链接添加到抓取列表中。 22 * @author Ada 23 * 24 */ 25 public class CnblogsByWebmagic implements PageProcessor{ 26 27 private Site site = Site.me() 28 .setRetryTimes(3) 29 .setSleepTime(1000) 30 .setTimeOut(10000) 31 .setCharset("utf-8") 32 .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"); 33 34 //实际请求地址:https://www.cnblogs.com/mvc/AggSite/PostList.aspx 35 public static final String URL_LIST = "https://www.cnblogs.com/mvc/AggSite/PostList.aspx"; 36 37 //页码 38 public static int pageNum = 1; 39 40 public static int count = 0; 41 42 //当前界面的链接地址:/html/body/div/div[4]/div[6]/div[3]/div[2]/h3/a 43 44 public void process(Page page) { 45 //用正则表达式判断当前页面是否为首页 46 if (page.getUrl().regex("^https://www\\.cnblogs\\.com$").match()) { 47 try { 48 page.addTargetRequests(page.getHtml().xpath("//div[@class=\"post_item_body\"]/h3/a/@href").all()); 49 pageNum ++; 50 //模拟POST请求 51 Request request = new Request(URL_LIST); 52 request.setMethod(HttpConstant.Method.POST); 53 54 //点击post请求右键选择复制 post 数据 55 request.setRequestBody(HttpRequestBody.json( 56 "{CategoryType:'SiteHome',ParentCategoryId:0,CategoryId:808,PageIndex:"+ 57 pageNum +",TotalPostCount:4000,ItemListActionName:'PostList'}", 58 "utf-8")); 59 60 page.addTargetRequest(request); 61 62 } catch (Exception e) { 63 e.printStackTrace(); 64 } 65 66 //爬取200页的数据 67 }else if (page.getUrl().regex(URL_LIST).match() && pageNum <= 200) { 68 try { 69 Thread.sleep(5000); 70 List<String> urls = page.getHtml().xpath("//div[@class='post_item_body']/h3/a/@href").all(); 71 page.addTargetRequests(urls); 72 73 //模拟POST请求 74 Request request = new Request(URL_LIST); 75 request.setMethod(HttpConstant.Method.POST); 76 77 //点击post请求右键选择复制 post 数据 78 request.setRequestBody(HttpRequestBody.json( 79 "{CategoryType:'SiteHome',ParentCategoryId:0,CategoryId:808,PageIndex:"+ 80 pageNum +",TotalPostCount:4000,ItemListActionName:'PostList'}", 81 "utf-8")); 82 83 page.addTargetRequest(request); 84 85 System.out.println("爬取第:"+ pageNum + "*********************************"); 86 87 } catch (Exception e) { 88 e.printStackTrace(); 89 } 90 } else { 91 page.putField("抓取的内容", page.getHtml().xpath("//a[@id='cb_post_title_url']/text()").toString()); 92 count ++; 93 } 94 95 } 96 97 98 public Site getSite() { 99 return site; 100 } 101 102 public static void main(String[] args) { 103 Spider.create(new CnblogsByWebmagic()).addUrl("https://www.cnblogs.com").thread(3).run(); 104 105 System.out.println("抓取了"+ count +"条数据"); 106 } 107 }View Code
这个我自认为是模拟的很像了,但是它不对,可能是我试验的还不够,我在之后会继续进行实验的,
今天就到此吧。