一、目标:
爬取博客园上的所有文章的标题,爬取不同页码的文章,将其在控制台输出。
二、要点:
模拟POST请求。实际请求地址。
三、步骤:
//模拟POST请求
Request request = new Request(URL_LIST);
request.setMethod(HttpConstant.Method.POST);
//点击post请求右键选择复制 post 数据
request.setRequestBody(HttpRequestBody.json(
"{CategoryType:'SiteHome',ParentCategoryId:0,CategoryId:808,PageIndex:"+
pageNum +",TotalPostCount:4000,ItemListActionName:'PostList'}",
"utf-8"));
四、代码:
package byMyself;
import java.util.List;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.model.HttpRequestBody;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.utils.HttpConstant;
/**
* 抓取博客园上的所有文章(一)
* 模拟POST请求
* 步骤:
* 1. F12查看源码,从网络查看实际请求地址,以及参数
* 2. 判断当前页面是否为主界面,若为主界面,将当前界面的链接添加到抓取列表
* 并模拟POST请求。
* 3. 若当前请求链接与实际链接相匹配,且请求的页码在范围内,用List 将链接
* 储存下来,并添加到抓取列表。模拟POST请求,将请求的页码的界面的所有
* 链接添加到抓取列表中。
* @author Ada
*
*/
public class CnblogsByWebmagic implements PageProcessor{
private Site site = Site.me().setRetryTimes(3).setSleepTime(1000).setTimeOut(10000).setCharset("utf-8")
.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");
//实际请求地址:https://www.cnblogs.com/mvc/AggSite/PostList.aspx
public static final String URL_LIST = "https://www.cnblogs.com/mvc/AggSite/PostList.aspx";
//页码
public static int pageNum = 1;
public static int count = 0;
//当前界面的链接地址:/html/body/div/div[4]/div[6]/div[3]/div[2]/h3/a
public void process(Page page) {
//用正则表达式判断当前页面是否为首页
if (page.getUrl().regex("^https://www\\.cnblogs\\.com$").match()) {
try {
page.addTargetRequests(page.getHtml().xpath("//div[@class=\"post_item_body\"]/h3/a/@href").all());
pageNum ++;
//模拟POST请求
Request request = new Request(URL_LIST);
request.setMethod(HttpConstant.Method.POST);
//点击post请求右键选择复制 post 数据
request.setRequestBody(HttpRequestBody.json(
"{CategoryType:'SiteHome',ParentCategoryId:0,CategoryId:808,PageIndex:"+
pageNum +",TotalPostCount:4000,ItemListActionName:'PostList'}",
"utf-8"));
page.addTargetRequest(request);
} catch (Exception e) {
e.printStackTrace();
}
//爬取200页的数据
}else if (page.getUrl().regex(URL_LIST).match() && pageNum <= 200) {
try {
Thread.sleep(5000);
List<String> urls = page.getHtml().xpath("//div[@class='post_item_body']/h3/a/@href").all();
page.addTargetRequests(urls);
//模拟POST请求
Request request = new Request(URL_LIST);
request.setMethod(HttpConstant.Method.POST);
//点击post请求右键选择复制 post 数据
request.setRequestBody(HttpRequestBody.json(
"{CategoryType:'SiteHome',ParentCategoryId:0,CategoryId:808,PageIndex:"+
++pageNum +",TotalPostCount:4000,ItemListActionName:'PostList'}",
"utf-8"));
page.addTargetRequest(request);
System.out.println("爬取第:"+ pageNum + "*********************************");
} catch (Exception e) {
e.printStackTrace();
}
} else {
page.putField("抓取的内容", page.getHtml().xpath("//a[@id='cb_post_title_url']/text()").toString());
count ++;
}
}
public Site getSite() {
return site;
}
public static void main(String[] args) {
Spider.create(new CnblogsByWebmagic()).addUrl("https://www.cnblogs.com").thread(3).run();
System.out.println("抓取了"+ count +"条数据");
}
}
五、总结:
在翻页时只有动态地址时,此时需要模拟POST请求。