c httpclient抓取网页(如何开发一个Java爬虫(的设计机制及原理))

优采云 发布时间: 2021-09-15 13:25

  c httpclient抓取网页(如何开发一个Java爬虫(的设计机制及原理))

  最近,我正在编写一个小爬虫来爬升一些网页数据,以便进行模型训练。在考虑如何抓取网页和分析网页时,我参考了OSC站的一些项目,特别是webmagic的设计机制和原理——如何开发@Huang Yihua编写的Java爬虫。Webmagic是一个垂直爬虫,我想写的是一个通用的爬虫,主要是爬上中文的网站内容。对于HTTP协议和消息处理,没有比httpclient组件更好的选择了。对于HTML代码解析,在比较了Htmlparser和jsoup之后,后者在API使用方面有明显的优势,简单易懂。在确定使用的开源组件之后,我们开始考虑如何捕获和解析这两个基本函数

  对于我的爬虫爬行功能,只需根据网页的URL抓取HTML代码,然后解析HTML代码中的链接和链接

  标记的文本是OK的,因此解析结果可以用page类表示。这个课程纯粹是一个POJO。如何使用httpclient和jsup直接解析为页面对象

  在httpclient4.2在中,提供了responsehandler来处理httpresponse。因此,通过实现此接口,可以将返回的HTML代码解析为所需的页面对象。其主要思想是读取httpresponse中的数据,将其转换为HTML代码,然后使用jsoup对其进行解析

  标签和标签。代码如下

  公共类PageResponseHandler实现ResponseHandler

  {

  private Page page;

public PageResponseHandler(Page page) {

this.page = page;

}

public void setPage(Page page) {

this.page = page;

}

public Page getPage() {

return page;

}

@Override

public Page handleResponse(HttpResponse response) throws ClientProtocolException, IOException {

StatusLine statusLine = response.getStatusLine();

HttpEntity entity = response.getEntity();

if (statusLine.getStatusCode() >= 300) {

EntityUtils.consume(entity);

throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());

}

if (entity == null)

return null;

// 利用HTTPClient自带的EntityUtils把当前HttpResponse中的HttpEntity转化成HTML代码

String html = EntityUtils.toString(entity);

Document document = Jsoup.parse(html);

Elements links = document.getElementsByTag("a");

for (int i = 0; i < links.size(); i++) {

Element link = links.get(i);

page.addAnchor(link.attr("href"), link.text());

}

// parse context of plain text from HTML code,

Elements paragraphs = document.getElementsByTag("p");

StringBuffer plainText = new StringBuffer(html.length() / 2);

for (int i = 0; i < paragraphs.size(); i++) {

Element paragraph = paragraphs.get(i);

plainText.append(paragraph.text()).append("\n");

}

page.setPlainText(plainText.toString());

return page;

}

  }

  代码不超过40行,非常简单。现在可以直接返回页面对象。编写一个测试类来测试pageresponsehandler。测试此类的函数不需要复杂的代码

  公共类页面响应HandlerTest{

  HttpClient httpclient;

PageResponseHandler pageResponseHandler;

final String url = "http://news.163.com/13/0903/11/97RHS2NS0001121M.html";

Page page = new Page(url);

@Before

public void setUp() throws Exception {

httpclient = new DefaultHttpClient();

HttpGet httpget = new HttpGet(url);

pageResponseHandler = new PageResponseHandler(page);

httpclient.execute(httpget, pageResponseHandler);

}

@After

public void tearDown() throws Exception {

httpclient.getConnectionManager().shutdown();

}

@Test

public void test() {

System.out.println(page.getPlainText());

assertTrue(page.getPlainText().length() > 0);

assertTrue(page.getAnchors().size() > 0);

}

  }

  到目前为止,该爬虫程序中的爬虫和分析功能运行良好。它也能很好地分析汉语。细心的读者会发现这些代码中没有字符集或字符集转换。稍后我们将讨论httpclient4.2组件中字符集的处理

  首先,回顾内容类型在HTTP协议RFC规范中的作用。它指示发送给收件人的HTTP实体内容的媒体类型。对于文本类型httpentity,它通常采用以下形式,指定httpentity的媒体类型以及用于编码的字符集。此外,RFC规范还规定,如果内容类型未指定字符集,则默认情况下使用iso-8859-1字符集对HTTP实体进行编码

  一,

  内容类型:text/html;字符集=UTF-8

  此时,您应该能够猜测httpclient4.2如何正确编码——也就是说,使用内容类型头中收录的字符集作为编码的输入源。有关特定代码,请参见entityutils类第212行开始的代码。Entityutils首先从httpentity对象获取内容类型。如果内容类型的字符集不是空的,它将使用内容类型对象中指定的字符集进行编码。否则,它将使用开发人员指定的字符集进行编码。如果开发人员未指定字符集,则使用默认字符集iso-8859-1进行编码。当然,编码是实现的,或者调用JDK的reader类

  ContentType ContentType=ContentType.getOrDefault(实体)

  Charset Charset=contentType.getCharset()

  if(字符集==null){

  charset=defaultCharset

  }

  if(字符集==null){

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线