寒假日报day7

最近在过年以及躲避疫情。。。。

汇报一下组一斤的收获吧,其实也不多,但是着实费了很大的力气,我现在正在修生养息阶段,接下来先着手一下其他方面的内容,

首先,关于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

这个我自认为是模拟的很像了,但是它不对,可能是我试验的还不够,我在之后会继续进行实验的,

今天就到此吧。

猜你喜欢

转载自www.cnblogs.com/msdog/p/12233583.html