使用HttpClient获取网页中动态加载的某部分数据,Java实现

缺点是需要人工寻找post请求的url和对应的参数。

参考:

1.为GET和POST请求添加请求参数和请求头 (使用HttpClient,Java)

2.关于抓取js加载出来的内容抓取 (参考了该博客的流程,例如找到实际的请求url)


以一篇新闻资讯为例:http://news.cqcoal.com/blank/nc.jsp?mid=98212

1.使用F12,在network中的文件列表中先找到该网页,双击弹出各项详细信息。“正文”查看该网页的内容,发现资讯对应的信息在网页没有显示,说明是后期加载上去的。

2.试着搜索文中的关键字,看看为获取数据,请求了哪些文件。例如搜索正文第一个词“海关总署”,可能会搜出多个文件,需要进行判断和选择。

对应的请求正文为“id: 98212”,即请求参数

3.查看“标头”

主要看请求url和请求方法,有时候需要设置user-agent。需要使用post方法

4.代码编写

 建立Java Maven项目,添加依赖:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.6</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.2.4</version>
</dependency>

下载的jar包见下图:

代码如下,我只获取了该文章的正文:

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.google.gson.Gson;

/**
 * http://news.cqcoal.com/blank/nc.jsp?mid=98212
 * 该网页的新闻主题是动态生成的,希望获取内容
 * @author yangc_cong
 *
 */
public class TestNewContent {
	
	/**
	 * 针对请求的链接,使用post方法获取返回的数据
	 * @param urlStr String类型
	 * @return 这里是Map类型
	 */
	private Map getPageContByHttpCl(String urlStr) {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpPost post = new HttpPost(urlStr);
		
		String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362";
		post.setHeader("User-Agent", userAgent);
		CloseableHttpResponse response = null;
		String result = null;
		// 创建请求参数

        List<NameValuePair> list = new LinkedList<NameValuePair>();
        BasicNameValuePair param1 = new BasicNameValuePair("id", "98212");
        list.add(param1);

        // 使用URL实体转换工具
        UrlEncodedFormEntity entityParam = null;
		try {
			entityParam = new UrlEncodedFormEntity(list, "UTF-8");
			post.setEntity(entityParam);
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
        
		try {
			response = httpclient.execute(post);
			HttpEntity entity = response.getEntity();
			result = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				response.close();
				httpclient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		System.out.println(result);

		Gson gson = new Gson();
		Map map = gson.fromJson(result, Map.class);
		return map;
	}
	
	private void parse_content(Map map) {
		//java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.Map
		ArrayList arrayList = (ArrayList)(map.get("rows"));
		Map innerMap = (Map) arrayList.get(0);
		String source = (String) innerMap.get("source");
		String bodyhtml = (String) innerMap.get("body");
		System.out.println("source: "+source);
		System.out.println("bodyhtml:"+'\n'+bodyhtml);
	}
	
	public static void main(String[] args) {
		TestNewContent test1 = new TestNewContent();
		String urlStr = "http://news.cqcoal.com/manage/newsaction.do?method:getNewsArchives";
		Map map = test1.getPageContByHttpCl(urlStr);
		test1.parse_content(map);
	}
}

运行截图:


补充:使用HtmlUnit来爬取该网页动态加载的正文部分(一个简单应用)

参考:HtmlUnit+Jsoup学习总结 

1.在maven项目中的配置

<!-- https://mvnrepository.com/artifact/net.sourceforge.htmlunit/htmlunit -->
<dependency>
    <groupId>net.sourceforge.htmlunit</groupId>
    <artifactId>htmlunit</artifactId>
    <version>2.27</version>
</dependency>

下载的jar包如下,有很多,所以建议使用maven进行配置:

2.代码部分(按照参考的博客进行编写的)

import java.io.IOException;
import java.net.MalformedURLException;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

public class HtmlUnitTest {
	public static void main(String[] args) {
		String url ="http://www.qidian.com";
		url = "http://news.cqcoal.com/blank/nc.jsp?mid=98212";
		// 1创建WebClient
		WebClient webClient=new WebClient(BrowserVersion.CHROME);
		// 2 启动JS
		webClient.getOptions().setJavaScriptEnabled(true);
		// 3 禁用Css,可避免自动二次請求CSS进行渲染
		webClient.getOptions().setCssEnabled(false);
		// 4 启动客戶端重定向
		webClient.getOptions().setRedirectEnabled(true);
		// 5 js运行错誤時,是否拋出异常
		webClient.getOptions().setThrowExceptionOnScriptError(false);
		// 6 设置超时
		webClient.getOptions().setTimeout(50000);       //获取网页
		HtmlPage htmlPage = null;
		try {
			htmlPage = webClient.getPage(url);
		} catch (FailingHttpStatusCodeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 等待JS驱动dom完成获得还原后的网页
		webClient.waitForBackgroundJavaScript(10000);
		// 网页内容  
		String pageHtml = htmlPage.asXml();
		System.out.println(pageHtml);
		System.out.println("\n------\n");
		//网页内容---纯文本形式
		String pageText = htmlPage.asText();
		System.out.println(pageText );
		
		//输出网页的title
		String title = htmlPage.getTitleText();
		System.out.println(title );

		//close
		webClient.close();
	}
}

3.运行结果(代码中要求输出加载js之后,包含标签的网页内容、纯文本---网页的文字部分、网页标题---即title属性的值。这里只贴出纯文本输出的部分结果)

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值