基于Webmagic的Java爬虫(四)爬取动态列表页内容

一、目标:
爬取博客园上的所有文章的标题,爬取不同页码的文章,将其在控制台输出。

二、要点:
模拟POST请求。实际请求地址。

三、步骤:

  1. 按F12查看源码,发现翻页处链接没有具体链接而是动态的地址,即在此页面不能直接取到所有的网页链接。
    基于Webmagic的Java爬虫(四)爬取动态列表页内容_第1张图片

  2. 点击翻页后按 F12 查看源码可发现实际请求地址。
    基于Webmagic的Java爬虫(四)爬取动态列表页内容_第2张图片

  3. 模拟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请求。

你可能感兴趣的:(基于Webmagic的Java爬虫(四)爬取动态列表页内容)