Java使用HtmlParser实现简单的网络爬虫
- 格式:doc
- 大小:87.00 KB
- 文档页数:5
java编写的⼀段简单的⽹络爬⾍demo代码功能:从⽹站上下载附件,并从页⾯中提取页⾯⽂章内容关于NIO在⼤多数情况下,Java 应⽤程序并⾮真的受着 I/O 的束缚。
操作系统并⾮不能快速传送数据,让 Java 有事可做;相反,是 JVM ⾃⾝在 I/O ⽅⾯效率⽋佳。
操作系统与 Java 基于流的 I/O模型有些不匹配。
操作系统要移动的是⼤块数据(缓冲区),这往往是在硬件直接存储器存取(DMA)的协助下完成的。
⽽ JVM 的 I/O 类喜欢操作⼩块数据——单个字节、⼏⾏⽂本。
结果,操作系统送来整缓冲区的数据,java.io 的流数据类再花⼤量时间把它们拆成⼩块,往往拷贝⼀个⼩块就要往返于⼏层对象。
操作系统喜欢整卡车地运来数据,java.io 类则喜欢⼀铲⼦⼀铲⼦地加⼯数据。
有了 NIO,就可以轻松地把⼀卡车数据备份到您能直接使⽤的地⽅(ByteBuffer 对象)。
以下代码使⽤了Java NIO以便提⾼⽂件读写效率。
java NIO与原始IO差别,可以阅读《Java NIO》中⽂版了解。
使⽤Xpath抓取⽂章中特定dom节点的内容。
代码如下(已测试,可⽤,注意修改具体被爬⾏⽹站的接⼝):import com.fasterxml.jackson.databind.ObjectMapper;import mon.collect.ImmutableMap;import mon.io.ByteStreams;import lombok.extern.slf4j.Slf4j;import mons.collections4.MapUtils;import ng3.RegExUtils;import ng3.StringUtils;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import ValuePair;import org.apache.http.client.config.RequestConfig;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.conn.ssl.SSLConnectionSocketFactory;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClientBuilder;import org.apache.http.message.BasicNameValuePair;import org.apache.http.ssl.SSLContextBuilder;import org.apache.http.util.EntityUtils;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.sax.InputSource;import .ssl.SSLContext;import javax.xml.xpath.XPath;import javax.xml.xpath.XPathConstants;import javax.xml.xpath.XPathExpressionException;import javax.xml.xpath.XPathFactory;import java.io.BufferedWriter;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.StringReader;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;import java.nio.charset.Charset;import java.nio.charset.StandardCharsets;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.nio.file.StandardOpenOption;import java.util.ArrayList;import java.util.Arrays;import java.util.LinkedHashSet;import java.util.List;import java.util.Map;import java.util.Set;import java.util.StringJoiner;import java.util.regex.Matcher;import java.util.regex.Pattern;import java.util.stream.Collectors;@Slf4jpublic class Main {private static Pattern pattern = pile("<div class=\"frame_subhead\">[\\s\\S]*?</div>");private static Pattern pattern2 = pile("<table class=\"form_table\">[\\s\\S]*?</table>");String base = "http://172.16.3.122:9000";Set<String> attachments = new LinkedHashSet<>();public static void main(String[] args) throws IOException {Main bootstrap = new Main();String jsonArray = bootstrap.getResponseBody("http://172.16.3.122:9000/pdfs");("爬⾍程序已启动...");bootstrap.attachments.addAll(bootstrap.getAttachments(jsonArray));boolean succeed = bootstrap.login("admin", "123456");("正在登陆⽹站获取cookie...");if (succeed) {List<String> sites = bootstrap.list();sites.forEach(site -> {try {bootstrap.crawl(site);} catch (IOException | XPathExpressionException e) {log.error("出错⽹站:{},{}",site,e);System.err.println("出错⽹站:"+site);e.printStackTrace();}});}}List<String> getAttachments(String rawArray) throws IOException {ObjectMapper objectMapper = new ObjectMapper();String[] attachments = objectMapper.readValue(rawArray, String[].class);return Arrays.asList(attachments);}void crawl(String site) throws IOException, XPathExpressionException {Path path = Paths.get(String.format("d:/download/%s", site));char[] chars = path.getFileName().toFile().getName().toCharArray();if ((int) chars[0] != 8195) {if (!Files.exists(path)) {Files.createDirectories(path);}downloadAttachment(site);List<Integer> array = Arrays.asList(3, 5, 6,7, 8);for (int i = 1; i <= 11; i++) {///昆⼭吉⼭会津塑料⼯业股份有限公司/html/1.htmlString url = String.format("%s/%s/html/%d.html", base, site, i);String html = getResponseBody(url);if (StringUtils.isNotBlank(html)) {String pattern = "tabContent_" + i;int start = html.indexOf(pattern);String title = extractSubTitle(start, html);Path file = Paths.get(String.format("d:/download/%s/%s.txt", site, title));if (array.contains(i)) {saveFile(start, file, html);}}}}}void xQuery(String text,Path path) throws IOException, XPathExpressionException {String xml = text.substring(text.indexOf("<tbody>"));StringJoiner joiner = new StringJoiner("","<root>","</root>");InputSource inputXML = new InputSource( new StringReader( joiner.add(xml).toString() ) );XPath xPath = XPathFactory.newInstance().newXPath();NodeList tBodyNodes = (NodeList) xPath.evaluate("/root/tbody", inputXML, XPathConstants.NODESET);try (BufferedWriter writer = Files.newBufferedWriter(path, Charset.defaultCharset(), StandardOpenOption.CREATE)) { for (int i = 0; i < tBodyNodes.getLength(); i++) {Node node = tBodyNodes.item(i);NodeList trNodes = (NodeList) xPath.evaluate("tr", node, XPathConstants.NODESET);for (int k = 0; k < trNodes.getLength(); k++) {NodeList childList = (NodeList) xPath.evaluate("td", trNodes.item(k), XPathConstants.NODESET);for (int j = 0; j < childList.getLength(); j++) {Node child = childList.item(j);String content = child.getTextContent();writer.write(content);if (j <childList.getLength() - 1) {writer.write("\t");}}writer.write("\r\n");}writer.write("\r\n");}}}void saveFile(int start,Path path, String html) throws XPathExpressionException, IOException {Matcher matcher = pattern2.matcher(html);int step = 0;String tableText = "";while (step++ < 1 && matcher.find(start)) {tableText = RegExUtils.replacePattern(matcher.group(), "<table class=\"form_table\">|</table>", "").trim();}xQuery(tableText,path);}void downloadAttachment(String site) {List<String> list = attachments.stream().filter(name -> name.startsWith(site)).collect(Collectors.toList());list.forEach(name -> {String filename = name.substring(stIndexOf("/") + 1);("正在下载 --{} -附件:{}", site, filename);String url = base + "/" + name;String dest = "d:/download/" + site + "/" + filename;Path file = Paths.get(dest).toAbsolutePath().normalize();if (!Files.exists(file)) {Path path = file.getParent();if (!Files.exists(path)) {("⾸次下载,正在创建⽬录:{}",path);try {Files.createDirectories(path);} catch (IOException e) {log.error("⽬录创建失败:{}",e);}}("正在保存采集来的附件,保存到:{}",file);try (FileChannel fc = new FileOutputStream(dest).getChannel()) {ByteBuffer buffer = getResponseAttachment(url);fc.write(buffer);("⽂件{}已经成功保存",file);} catch (IOException e) {log.error("⽂件{}保存出错:{}",file,e);}}});}List<String> list() throws IOException {String url = base + "/%E5%88%97%E8%A1%A8%E9%A1%B5%E9%9D%A2/%E6%B1%9F%E8%8B%8F%E7%9C%81%E9%AB%98%E6%96%B0%E6%8A%80%E6%9C%AF%E4%BC%81%E4%B8%9A%E8%BE%85%E5%8A%A9% return Files.list(Paths.get("E:\\pdf")).map(path -> path.getFileName().toFile().getName()).filter(path -> (!path.startsWith(" ")) && !path.startsWith(" ")).filter(dirName -> {return !Arrays.asList("登录⽹页", "列表页⾯").contains(dirName);}).collect(Collectors.toList());}boolean login(String username, String password) {String url = base + "/index.html";ImmutableMap<String, String> map = ImmutableMap.<String, String>builder().put("username", "admin").put("password", "123456").build();try {HttpResponse response = doPost(url, null, map);return true;} catch (IOException e) {log.error("登录出错:{}", e);;return false;}}/*** 信任SSL证书** @return*/public CloseableHttpClient buildDefaultHttpClientTrustSSL() {SSLContext sslContext = null;try {sslContext = SSLContextBuilder.create().useProtocol(SSLConnectionSocketFactory.SSL).loadTrustMaterial((x, y) -> true).build();} catch (Exception e) {e.printStackTrace();}RequestConfig config = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(30000).setConnectionRequestTimeout(30000).setContentCompressionEnabled(true).build();return HttpClientBuilder.create().setDefaultRequestConfig(config).setSSLContext(sslContext).setSSLHostnameVerifier((x, y) -> true).build();}/**** 从响应的报⽂中提取⽹站标题* @param responseBody* @return*/public String extractSubTitle(int start, String responseBody) {Matcher matcher = pattern.matcher(responseBody);int i = 0;String subHead = "";while (i++ < 1 && matcher.find(start)) {subHead = StringUtils.replacePattern(matcher.group(), "<div class=\"frame_subhead\">|</div>", "").trim();}int offset1 = subHead.indexOf("、");if (offset1 >= 0) {subHead = subHead.substring(offset1 + 1);}return subHead;}public String extract(String body, String pattern) {Pattern regex = pile(pattern);return "";}HttpResponse doGet(String url, Map<String, String> headerRefs) throws IOException {//巡检时更改为信任证书CloseableHttpClient httpClient = buildDefaultHttpClientTrustSSL();HttpGet httpGet = new HttpGet(url);httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64)spider");httpGet.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");httpGet.addHeader("Accept-Encoding", "gzip, deflate");httpGet.addHeader("Accept-Language", "zh-CN,zh;q=0.9");if (MapUtils.isNotEmpty(headerRefs)) {for (Map.Entry<String, String> entry : headerRefs.entrySet()) {String name = entry.getKey();String value = entry.getValue();httpGet.setHeader(name, value);}}return httpClient.execute(httpGet);}HttpResponse doPost(String url, Map<String, String> headerRefs, Map<String, String> data) throws IOException {//巡检时更改为信任证书CloseableHttpClient httpClient = buildDefaultHttpClientTrustSSL();HttpPost httpPost = new HttpPost(url);httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) spider");httpPost.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");httpPost.addHeader("Accept-Encoding", "gzip, deflate");httpPost.addHeader("Accept-Language", "zh-CN,zh;q=0.9");if (MapUtils.isNotEmpty(headerRefs)) {for (Map.Entry<String, String> entry : headerRefs.entrySet()) {String name = entry.getKey();String value = entry.getValue();httpPost.setHeader(name, value);}}if (MapUtils.isNotEmpty(data)) {List<NameValuePair> nvps = new ArrayList<NameValuePair>();for (Map.Entry<String, String> entry : data.entrySet()) {String name = entry.getKey();String value = entry.getValue();nvps.add(new BasicNameValuePair(name, value));}httpPost.setEntity(new UrlEncodedFormEntity(nvps));}return httpClient.execute(httpPost);}/**** 下载附件* @param url* @param headerRefs* @return* @throws IOException*/ByteBuffer getResponseAttachment(String url, Map<String, String> headerRefs) throws IOException {HttpResponse response = doGet(url, headerRefs);HttpEntity entity = response.getEntity();if (entity != null) {try (InputStream responseStream = entity.getContent()) {byte[] targetArray = ByteStreams.toByteArray(responseStream);ByteBuffer bufferByte = ByteBuffer.wrap(targetArray);return bufferByte;}}return ByteBuffer.wrap(new byte[0]);}ByteBuffer getResponseAttachment(String url) throws IOException {return getResponseAttachment(url, null);}/**** 下载html响应报⽂主题(html代码)* @param url* @param headerRefs* @param charset* @return* @throws IOException*/String getResponseBody(String url, Map<String, String> headerRefs, Charset charset) throws IOException { HttpResponse response = doGet(url, headerRefs);int status = response.getStatusLine().getStatusCode();if (status != 200) {return "";}HttpEntity entity = response.getEntity();if (entity != null) {return EntityUtils.toString(entity, charset);}return "";}String getResponseBody(String url, Charset charset) throws IOException {return getResponseBody(url, null, charset);}String getResponseBody(String url) throws IOException {return getResponseBody(url, null, StandardCharsets.UTF_8);}}。
使用JAVA进行网络爬虫和数据抓取的方法与建议一、引言随着互联网的快速发展,网络上的数据量也在不断增长。
为了获取和分析这些数据,网络爬虫和数据抓取成为了一种重要的技术手段。
本文将介绍使用JAVA进行网络爬虫和数据抓取的方法与建议。
二、网络爬虫的原理网络爬虫是一种自动化程序,通过模拟浏览器的行为,访问网页并抓取其中的数据。
其主要原理包括以下几个步骤:1. 发送HTTP请求:通过JAVA的网络编程库,发送HTTP请求到目标网址。
2. 下载网页内容:获取到HTTP响应后,将网页内容下载到本地。
3. 解析网页内容:使用HTML解析库,解析网页的结构,提取出需要的数据。
4. 存储数据:将提取到的数据存储到数据库或者文件中。
三、JAVA网络编程库的选择在使用JAVA进行网络爬虫和数据抓取之前,我们需要选择一个适合的网络编程库。
常用的网络编程库有Apache HttpClient、OkHttp等。
这些库提供了丰富的API,可以方便地发送HTTP请求和处理HTTP响应。
四、HTML解析库的选择HTML解析库可以帮助我们解析网页的结构,提取出需要的数据。
常用的HTML解析库有Jsoup、HtmlUnit等。
这些库提供了简洁的API,可以方便地进行网页解析和数据提取。
五、设置合适的请求头在发送HTTP请求时,我们需要设置合适的请求头。
一些网站可能会对爬虫进行限制,通过设置合适的请求头可以模拟浏览器的行为,降低被封禁的风险。
常见的请求头包括User-Agent、Referer等。
六、处理反爬机制为了防止被爬虫抓取,一些网站会采取一些反爬机制,如验证码、IP封禁等。
在进行网络爬虫和数据抓取时,我们需要针对这些反爬机制进行相应的处理。
可以通过使用代理IP、使用验证码识别库等方式来应对反爬机制。
七、数据存储与处理在进行数据抓取之后,我们需要将抓取到的数据进行存储和处理。
可以选择将数据存储到数据库中,如MySQL、MongoDB等;也可以选择将数据存储到文件中,如CSV、JSON等。
Java爬⾍利器HTML解析⼯具-JsoupJsoup简介Java爬⾍解析HTML⽂档的⼯具有:htmlparser, Jsoup。
本⽂将会详细介绍Jsoup的使⽤⽅法,10分钟搞定Java爬⾍HTML解析。
Jsoup可以直接解析某个URL地址、HTML⽂本内容,它提供⾮常丰富的处理Dom树的API。
如果你使⽤过JQuery,那你⼀定会⾮常熟悉。
Jsoup最强⼤的莫过于它的CSS选择器⽀持了。
⽐如:document.select("div.content > div#image > ul > li:eq(2)。
包引⼊⽅法Maven添加下⾯的依赖声明即可,最新版本是(1.12.1)<dependency><!-- jsoup HTML parser library @ https:/// --><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.11.3</version></dependency>Gradle// jsoup HTML parser library @ https:///compile 'org.jsoup:jsoup:1.11.3'源码安装当然也可以直接把jar包下载下来,下载地址:# git获取代码git clone https:///jhy/jsoup.gitcd jsoupmvn install# 下载代码curl -Lo jsoup.zip https:///jhy/jsoup/archive/master.zipunzip jsoup.zipcd jsoup-mastermvn installJsoup解析⽅法Jsoup⽀持四种⽅式解析Document,即可以输⼊四种内容得到⼀个Document:解析字符串解析body⽚段从⼀个URL解析从⼀个⽂件解析字符串解析⽰例字符串中必须包含head和body元素。
java爬虫抓取网页数据教程数据是科研活动重要的基础,而爬虫是获取数据一个比较常见的方法,爬虫的基本原理很简单,就是利用程序访问互联网,然后将数据保存到本地中。
我们都知道,互联网提供的服务大多数是以网站的形式提供的。
我们需要的数据一般都是从网站中获取的,如电商网站商品信息、商品的评论、微博的信息等。
爬虫和我们手动将看到的数据复制粘贴下来是类似的,只是获取大量的数据靠人工显然不太可能。
因此,需要我们使用工具来帮助获取知识。
使用程序编写爬虫就是使用程序编写一些网络访问的规则,将我们的目标数据保存下来。
Java作为爬虫语言的一种,下面为大家介绍java爬虫抓取网页数据教程。
1、使用bbbClient简单抓取网页首先,假设我们需要爬取数据学习网站上第一页的博客(bbb://aaadatalearneraaa/blog)。
首先,我们需要使用导入bbbClient 4.5.3这个包(这是目前最新的包,你可以根据需要使用其他的版本)。
Java本身提供了关于网络访问的包,在中,然后它不够强大。
于是Apache基金会发布了开源的bbb请求的包,即bbbClient,这个包提供了非常多的网络访问的功能。
在这里,我们也是使用这个包来编写爬虫。
好了,使用pom.xml下载完这个包之后我们就可以开始编写我们的第一个爬虫例子了。
其代码如下(注意,我们的程序是建立在test包下面的,因此,需要在这个包下才能运行):package test;import org.apache.bbb.bbbEntity;importorg.apache.bbb.client.methods.CloseablebbbResponse;import org.apache.bbb.client.methods.bbbGet;importorg.apache.bbb.impl.client.CloseablebbbClient;importorg.apache.bbb.impl.client.bbbClients;importorg.apache.bbb.util.EntityUtils;import java.io.IOException;/*** 第一个爬虫测试* Created by DuFei on 2017/7/27.*/public class FirstTest {public static void main(String[] args) {//建立一个新的请求客户端CloseablebbbClient bbbClient =bbbClients.createDefault();//使用bbbGet方式请求网址bbbGet bbbGet = new bbbGet("bbb://aaadatalearneraaa/blog");//获取网址的返回结果CloseablebbbResponse response = null;try {response = bbbClient.execute(bbbGet);} catch (IOException e) {e.printStackTrace();}//获取返回结果中的实体bbbEntity entity = response.getEntity();//将返回的实体输出try {System.out.println(EntityUtils.toString(entity));EntityUtils.consume(entity);} catch (IOException e) {e.printStackTrace();}}}如上面的代码所示,爬虫的第一步需要构建一个客户端,即请求端,我们这里使用CloseablebbbClient作为我们的请求端,然后确定使用哪种方式请求什么网址,再然后使用bbbResponse获取请求的位置对应的结果即可。
声明:本人来自转载/HTMLParser具有小巧,快速的优点,缺点是相关文档比较少(英文的也少),很多功能需要自己摸索。
对于初学者还是要费一些功夫的,而一旦上手以后,会发现HTMLParser 的结构设计很巧妙,非常实用,基本你的各种需求都可以满足。
这里我根据自己这几个月来的经验,写了一点入门的东西,希望能对新学习HTMLParser 的朋友们有所帮助。
(不过当年高考本人语文只比及格高一分,所以文法方面的问题还希望大家多多担待)HTMLParser的核心模块是org.htmlparser.Parser类,这个类实际完成了对于HTML页面的分析工作。
这个类有下面几个构造函数:public Parser ();public Parser (Lexer lexer, ParserFeedback fb);public Parser (URLConnection connection, ParserFeedback fb) throws ParserException; public Parser (String resource, ParserFeedback feedback) throws ParserException; public Parser (String resource) throws ParserException;public Parser (Lexer lexer);public Parser (URLConnection connection) throws ParserException;和一个静态类public static Parser createParser (String html, String charset);对于大多数使用者来说,使用最多的是通过一个URLConnection或者一个保存有网页内容的字符串来初始化Parser,或者使用静态函数来生成一个Parser对象。
package parser;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import .MalformedURLException;import .URL;/*** 基本能实现网页抓取,不过要手动输入URL 将整个html内容保存到指定文件** @author chenguoyong**/public class ScrubSelectedWeb {private final static String CRLF = System.getProperty("line.separator");/*** @param args*/public static void main(String[] args) {try {URL ur = new URL("http://10.249.187.199:8083/injs100/");InputStream instr = ur.openStream();String s, str;BufferedReader in = new BufferedReader(new InputStreamReader(instr));StringBuffer sb = new StringBuffer();BufferedWriter out = new BufferedWriter(new FileWriter("D:/outPut.txt"));while ((s = in.readLine()) != null) {sb.append(s + CRLF);}System.out.println(sb);str = new String(sb);out.write(str);out.close();in.close();} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}如上是基本能实现网页抓取,不过要手动输入URL,此外没有重构。
java 爬虫案例Java爬虫案例1. 爬取网页内容Java爬虫可以通过发送HTTP请求获取网页的内容。
可以使用Java 的URLConnection或者HttpClient等工具类库发送GET或POST请求,并获取返回的网页内容。
通过解析网页的HTML结构,可以提取出所需的信息。
2. 提取网页中的链接爬虫可以通过解析网页的HTML结构,提取出所有的链接。
可以使用Java的正则表达式、Jsoup等工具来解析网页。
通过遍历网页中的链接,可以进一步获取其他网页的内容。
3. 爬取图片Java爬虫可以通过解析网页的HTML结构,提取出图片的链接,然后使用Java的IO流将图片保存到本地或者其他存储介质中。
可以使用Java的正则表达式、Jsoup等工具来解析网页,并使用Java 的IO流进行文件的读写操作。
4. 爬取表格数据Java爬虫可以通过解析网页的HTML结构,提取出表格中的数据。
可以使用Java的正则表达式、Jsoup等工具来解析网页,并通过遍历表格的行和列,提取出所需的数据。
5. 登录网站爬取数据有些网站需要登录才能获取到数据,Java爬虫可以模拟登录过程,发送POST请求并携带登录信息,然后获取登录后的网页内容。
可以使用Java的URLConnection或者HttpClient等工具类库发送POST 请求,并获取返回的登录后的网页内容。
6. 爬取动态网页有些网页内容是通过JavaScript动态生成的,Java爬虫可以使用无头浏览器(headless browser)来模拟浏览器的行为,执行JavaScript代码,并获取动态生成的网页内容。
可以使用Java的Selenium等工具来模拟浏览器的行为。
7. 爬取API数据有些网站提供了API接口,Java爬虫可以通过发送HTTP请求并携带相应的参数,获取API返回的数据。
可以使用Java的URLConnection或者HttpClient等工具类库发送HTTP请求,并解析API返回的数据。
深入理解JAVA的网络爬虫与搜索引擎引言:随着互联网的快速发展,我们每天都会面临大量的信息。
为了更高效地获取我们需要的信息,网络爬虫和搜索引擎成为了必不可少的工具。
而作为一种常用的编程语言,JAVA在网络爬虫和搜索引擎的开发中扮演着重要的角色。
本文将深入理解JAVA的网络爬虫与搜索引擎的原理、应用以及相关技术。
一、网络爬虫的原理与应用1.1 网络爬虫的原理网络爬虫是一种自动化程序,通过模拟人类浏览器的行为,自动访问互联网上的网页并提取有用的信息。
其原理主要分为以下几个步骤:首先,网络爬虫需要指定一个起始网址,也称为种子URL。
然后,它会通过HTTP协议向服务器发送请求,获取网页的HTML源代码。
接下来,爬虫会解析HTML源代码,提取出页面中的链接,并将这些链接添加到待爬取的URL队列中。
然后,爬虫会从URL队列中取出一个URL,并重复前面的步骤,直到队列为空或达到设定的爬取深度。
最后,爬虫会将提取到的有用信息进行处理和存储,以供后续的分析和应用。
1.2 网络爬虫的应用网络爬虫在各个领域都有广泛的应用,以下是一些常见的应用场景:搜索引擎:搜索引擎通过网络爬虫来获取互联网上的网页信息,并建立索引以供用户搜索。
数据挖掘:网络爬虫可以用于获取大量的数据,用于分析和挖掘有用的信息。
舆情监测:通过网络爬虫可以实时监测社交媒体、新闻网站等发布的信息,用于舆情分析和预警。
价格比较:一些电商网站使用网络爬虫来获取竞争对手的价格信息,以便制定自己的价格策略。
二、JAVA网络爬虫的开发2.1 JAVA网络爬虫的基本框架在JAVA中,我们可以使用一些开源的网络爬虫框架来简化开发过程。
比较常用的有Jsoup、HttpClient和WebMagic等。
Jsoup是一款优秀的HTML解析器,可以方便地解析HTML源代码,并提供了丰富的API来获取和操作页面中的元素。
HttpClient是一个功能强大的HTTP客户端库,可以模拟浏览器的行为,发送HTTP请求并获取响应。
在进行下述例子之前,请添加上面所用到的依赖包!1、通过HTMLParser将网页下载到本地String localFile = "F:\\temp\\temp.html";try {// HttpClient主要负责执行请求HttpClient httpClient = new DefaultHttpClient();// 利用HTTP GET 向服务器发起请求HttpGet get = new HttpGet("");//里面参数为要爬取的网址,假如你的网址是那么这里就填写你的网址// 获得服务器响应的所有消息HttpResponse response = httpClient.execute(get);// 获得服务器响应回来的消息体(不包括HTTP HEAD)HttpEntity entity = response.getEntity();if (entity != null) {// 获取编码信息String charset = EntityUtils.getContentCharSet(entity);InputStream is = entity.getContent();IOUtils.copy(is, new FileOutputStream(localFile));}// 获得所有的链接资源,一般在所有的请求处理完成之后,才需要释放httpClient.getConnectionManager().shutdown();} catch (Exception e) {}2、提取网页中图片的链接地try {// 把文件的内容读进来String html = IOUtils.toString(new FileInputStream(localFile),"UTF-8");// 创建一个HTML解释器Parser parser = new Parser();parser.setInputHTML(html);// 图片节点NodeList imageTags = parser.parse(new NodeClassFilter(ImageTag.class));System.out.println(imageTags.size());for (int i = 0, size = imageTags.size(); i < size; i++) {ImageTag it = (ImageTag) imageTags.elementAt(i);String imageUrl = it.getImageURL();System.out.println(imageUrl);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (ParserException e) {e.printStackTrace();}3、提取具有某种特征的标签try {// 把文件的内容读进来String html = IOUtils.toString(new FileInputStream(localFile), "UTF-8");// 创建一个HTML解释器Parser parser = new Parser();parser.setInputHTML(html);// 提取name="title"的meta标签NodeList metaTags = parser.parse(new NodeFilter() {public boolean accept(Node node) {if (node instanceof MetaTag) {MetaTag mt = (MetaTag) node;if (mt.getMetaTagName() != null&& mt.getMetaTagName().equals("description")) {return true;}}return false;}});System.out.println(metaTags.size());for (int i = 0, size = metaTags.size(); i < size; i++) { MetaTag it = (MetaTag) metaTags.elementAt(i);System.out.println("文章的description:"+it.getMetaContent()); }} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (ParserException e) {e.printStackTrace();}。
JAVA多线程⽹络爬⾍的代码实现原创作品,允许转载,转载时请务必以超链接形式标明⽂章、作者信息和本声明。
否则将追究法律责任。
因为项⽬需要,做了⼀个⽹络爬⾍的⼩DEMO。
为实现⾼性能的⽹络爬⾍,⾸先考虑采⽤APACE的HttpClient进⾏页⾯的采集和解析,HttpClient可以很⽅便的通过URL获得远程内容,例如⼀个⼩程序:12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 CloseableHttpClienthttp client = HttpClients.createDefault();HttpGet httpget = new HttpGet("http://localhost/");CloseableHttpResponse response = httpclient.execute(httpget); try{HttpEntity entity =response.getEntity();if(entity != null) {long len =entity.getContentLength();if(len != -1&& len <2048) {System.out.println(EntityUtils.toString(entity));} else{// Stream contentout}}}finally{response.close();}还可以做页⾯解析和模拟登陆等,功能相当强⼤。
其次,如果是⽹络爬⾍或者⽹络采集,可能需要做⼤量的URL地址收集和分析,所以需要通过NoSQL数据库来提⾼执⾏的效率,Redis、Memcache、BerkeleyDB都是不错的选择。
这⾥选择了BerkeleyDB数据库。
虽然采⽤传统队列或其他形式可能性能会更⾼,但会带来⼤量的内存消耗,并不⼀定能找到符合条件的⼤内存服务器。
Java使用HtmlParser实现简单的网络爬虫目的Java 使用HtmlParser 抓取网页数据并解析。
效果图例如:抓取12306网站中货物运价率的数据源代码package com.zc.test;import .HttpURLConnection;import .URL;import org.htmlparser.Node;import org.htmlparser.NodeFilter;import org.htmlparser.Parser;import org.htmlparser.filters.AndFilter;import org.htmlparser.filters.HasAttributeFilter;import org.htmlparser.filters.TagNameFilter;import org.htmlparser.nodes.TagNode;import org.htmlparser.tags.TableColumn;import org.htmlparser.tags.TableRow;import org.htmlparser.tags.TableTag;import org.htmlparser.util.NodeList;/*** @Description java爬虫测试类* @author张川(cr10210206@)* @data2013-11-27 10:01:13*/public class JavaCrawler {/*** 测试* */public static void main(String[] args) {JavaCrawler test = new JavaCrawler();//货物运价率test.getGoodFareData("/hyinfo/action/JgxxActi on_hwyjl?lx=00");//危险品运输栏目危险品栏目内容//test.getDangerDivData("/hyinfo/page/home-frei ghtProduction-Dangerous_index");//超限超重栏目超限超重栏目内容//test.getDangerDivData("/hyinfo/page/home-frei ghtProduction-overweight_index");}/*** 获取 Parser 对象** @param url 网络地址* */public static Parser getParser(String url){try {Parser parser = new Parser((HttpURLConnection) new URL(url).openConnection());//数据源parser.setEncoding("UTF-8");//编码return parser;} catch (Exception e) {e.printStackTrace();}return null;}/*** 获取货物运价率数据** @param url 网络地址*/public void getGoodFareData(String url) {try {//解析器Parser parser = getParser(url);//标签过滤,第一个参数代表过滤的哪个标签,第二个参数代表过滤标签的哪个属性NodeFilter divFilter = new AndFilter(new TagNameFilter("table"),new HasAttributeFilter("id","T1"));//把过滤后的内容加入NodeList里进行遍历NodeList nodeList = parser.extractAllNodesThatMatch(divFilter);TableTag tableTag = (TableTag) nodeList.elementAt(0);//获取Table对象TableRow[] tableRows = tableTag.getRows();//获取行数组 String andstr = " ";System.out.println("类别名称运价号基价1单位基价1标准基价2单位基价2标准");for (int i = 2; i < tableRows.length; i++) {TableRow tableRow = tableRows[i];TableColumn[] tableColumns = tableRow.getColumns();//获取列数组String typeName = tableColumns[0].getStringText().replace(andstr, "").trim();String fareid = tableColumns[1].getStringText().replace(andstr, "").trim();String price1Unit = tableColumns[2].getStringText().replace(andstr, "").trim();String price1St = tableColumns[3].getStringText().replace(andstr, "").trim();String price2Unit = tableColumns[4].getStringText().replace(andstr, "").trim();String price2St = tableColumns[5].getStringText().replace(andstr, "").trim();System.out.println(typeName + " " + fareid + "" + price1Unit + " " + price1St + " " + price2Unit + "" + price2St);}} catch (Exception e) {e.printStackTrace();}}/*** 获取危险品运输栏目数据** @param url 网络地址* */public void getDangerDivData(String url){try {//解析器Parser parser = getParser(url);//标签过滤,第一个参数代表过滤的哪个标签,第二个参数代表过滤标签的哪个属性NodeFilter divFilter = new AndFilter(new TagNameFilter("div"),new HasAttributeFilter("class","cleft"));//把过滤后的内容加入NodeList里进行遍历NodeList nodeList = parser.extractAllNodesThatMatch(divFilter);Node node = nodeList.elementAt(0);NodeList childNodeList = node.getChildren();if(childNodeList != null && childNodeList.size() > 0){System.out.println("\n\n栏目标识栏目名称");for (int i = 0; i < childNodeList.size(); i++) {Node childNode = childNodeList.elementAt(i);if(childNode instanceof TagNode){TagNode tag = (TagNode) childNode;String id = tag.getAttribute("id");String value = tag.toPlainTextString();if(id != null){System.out.println(id + " " + value);url = url.substring(0,url.indexOf("_")+1) + id;System.out.println("[" + value + "]的内容如下:\n");this.getDangerContent(url);System.out.println("------------------------------------------------------------------------------------------------");}}}}} catch (Exception e) {e.printStackTrace();}}/*** 危险品栏目内容** @param url 网络地址* */public void getDangerContent(String url){try {//解析器Parser parser = getParser(url);//标签过滤,第一个参数代表过滤的哪个标签,第二个参数代表过滤标签的哪个属性NodeFilter divFilter = new AndFilter(new TagNameFilter("div"),new HasAttributeFilter("class","cright"));//把过滤后的内容加入NodeList里进行遍历NodeList nodeList = parser.extractAllNodesThatMatch(divFilter);Node node = nodeList.elementAt(0);System.out.println(node.toHtml());} catch (Exception e) {e.printStackTrace();}}}。