重庆人才招聘网最新招聘2022,网站优化软件排名器,wordpress文章参数,wordpress更改背景参考#xff1a;http://www.cnblogs.com/dongkuo/p/4851735.html算法分析我们现在从需求中提取关键词来逐步分析问题。 首先是“种子节点”。它就是一个或多个在爬虫程序运行前手动给出的URL#xff08;网址#xff09;#xff0c;爬虫正是下载并解析这些种子URL指向的页面… 参考http://www.cnblogs.com/dongkuo/p/4851735.html 算法分析 我们现在从需求中提取关键词来逐步分析问题。 首先是“种子节点”。它就是一个或多个在爬虫程序运行前手动给出的URL网址爬虫正是下载并解析这些种子URL指向的页面从中提取出新的URL然后重复以上的工作直到达到设定的条件才停止。 然后是“特定的策略”。这里所说的策略就是以怎样的顺序去请求这些URL。如下图是一个简单的页面指向示意图实际情况远比这个复杂页面A是种子节点当然最先请求。但是剩下的页面该以何种顺序请求呢我们可以采用深度优先遍历策略通俗讲就是一条路走到底走完一条路才再走另一条路在下图中就是按ABCFDGEH的顺序访问。我们也可以采用宽度优先遍历策略就是按深度顺序去遍历在下图中就是按ABCDEFGH的顺序请求各页面。还有许多其他的遍历策略如Google经典的PageRank策略OPIC策略策略大站优先策略等这里不一一介绍了。我们还需要注意的一个问题是很有可能某个页面被多个页面同时指向这样我们可能重复请求某一页面因此我们还必须过滤掉已经请求过的页面。 最后是“设定的条件”爬虫程序终止的条件可以根据实际情况灵活设置比如设定爬取时间爬取数量爬行深度等。 到此我们分析完了爬虫如何开始怎么运作如何结束当然要实现一个强大完备的爬虫要考虑的远比这些复杂这里只是入门分析下面给出整个运作的流程图 数据结构分析 根据以上的分析我们需要用一种数据结构来保存初始的种子URL和解析下载的页面得到的URL并且我们希望先解析出的URL先执行请求因此我们用队列来储存URL。因为我们要频繁的添加取出URL因此我们采用链式存储。下载的页面解析后直接原封不动的保存到磁盘。 技术分析 所谓网络爬虫我们当然要访问网络我们这里使用jsoup它对http请求和html解析都做了良好的封装使用起来十分方便。根据数据结构分析我们用LinkedList实现队列用来保存未访问的URL用HashSet来保存访问过的URL因为我们要大量的判断该URL是否在该集合内而HashSet用元素的Hash值作为“索引”查找速度很快。 代码 以上分析我们一共要实现2个类 ① JsoupDownloader该类是对Jsoup做一个简单的封装方便调用。暴露出以下几个方法 —public Document downloadPage(String url)根据url下载页面 —public SetString parsePage(Document doc, String regex)从Document中解析出匹配regex的url。 —public void savePage(Document doc, String saveDir, String saveName, String regex)保存匹配regex的url对应的Document到指定路径。 ② UrlQueue该类用来保存和获取URL。暴露出以下几个方法 —public void enQueue(String url)添加url。 —public String deQueue()取出url。 —public int getVisitedCount()获取访问过的url的数量 package com.hjzgg.spider;import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.SocketTimeoutException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;import org.jsoup.Connection;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;public class JsoupDownloader {public static final String DEFAULT_SAVE_DIR c:/download/;private static JsoupDownloader downloader;private JsoupDownloader() {}public static JsoupDownloader getInstance() {if (downloader null) {synchronized (JsoupDownloader.class) {if (downloader null) {downloader new JsoupDownloader();}}}return downloader;}public Document downloadPage(String url) {try {System.out.println(正在下载 url);Connection connection Jsoup.connect(url);connection.timeout(1000);connection.followRedirects(false);//默认是true也就是连接遵循重定向设置为false对重定向的地址进行筛选Response response connection.execute();MapString, String headers response.headers();System.out.println(response.statusCode() response.statusMessage());if(response.statusCode()301 || response.statusCode()302){重定向地址位于信息头header中Main.urlQueue.enQueue(headers.get(Location));} else if(response.statusCode() 404){//或者一些其他的错误信息直接将改地址丢弃return null;}for(String name : headers.keySet())//在这里可以查看http的响应信息头信息System.out.println(name : headers.get(name));return connection.get();} catch(SocketTimeoutException e){//对于连接超时的url我们可以重新将其放入未访问url队列中Main.urlQueue.enQueueUrlTimeOut(url);}catch (IOException e) {e.printStackTrace();}return null;}public SetString parsePage(Document doc, String regex) {SetString urlSet new HashSetString();if (doc ! null) {Elements elements doc.select(a[href]);for (Element element : elements) {String url element.attr(href);if (url.length() 6 !urlSet.contains(url)) {if (regex ! null !url.matches(regex)) {continue;}if(!url.contains(http))url doc.baseUri()url;urlSet.add(url);}}}return urlSet;}public void savePage(Document doc, String saveDir, String saveName, String regex) {if (doc null) {return;}if (regex ! null doc.baseUri() ! null !doc.baseUri().matches(regex)) {return;}saveDir saveDir null ? DEFAULT_SAVE_DIR : saveDir;saveName saveName null ? doc.title().trim().replaceAll([\\?/:\\*|\ ], _) System.nanoTime() .html : saveName;File file new File(saveDir / saveName);File dir file.getParentFile();if (!dir.exists()) {dir.mkdirs();}PrintWriter printWriter;try {printWriter new PrintWriter(file);printWriter.write(doc.toString());printWriter.close();} catch (FileNotFoundException e) {e.printStackTrace();}}
} package com.hjzgg.spider;import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.NoSuchElementException;
import java.util.Set;public class UrlQueue {private SetString visitedSet;// 用来存放已经访问过多urlprivate LinkedListString unvisitedList;// 用来存放未访问过多urlpublic UrlQueue(String[] seeds) {visitedSet new HashSetString();unvisitedList new LinkedListString();unvisitedList.addAll(Arrays.asList(seeds));}/*** 添加url* * param url*/public void enQueue(String url) {if (url ! null !visitedSet.contains(url)) {unvisitedList.addLast(url);}}/*** 添加访问超时的url* * param url*/public void enQueueUrlTimeOut(String url) {if (url ! null) {visitedSet.remove(url);unvisitedList.addLast(url);}}/*** 添加url* * param urls*/public void enQueue(CollectionString urls) {for (String url : urls) {enQueue(url);}}/*** 取出url* * return*/public String deQueue() {try {String url unvisitedList.removeFirst();while(visitedSet.contains(url)) {url unvisitedList.removeFirst();}visitedSet.add(url);return url;} catch (NoSuchElementException e) {System.err.println(URL取光了);}return null;}/*** 得到已经请求过的url的数目* * return*/public int getVisitedCount() {return visitedSet.size();}
} package com.hjzgg.spider;import java.util.Set;import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;public class Main {static UrlQueue urlQueue new UrlQueue(new String[] { http://192.168.1.201:8080/HZML/ });public static void main(String[] args) {JsoupDownloader downloader JsoupDownloader.getInstance();long start System.currentTimeMillis();while (urlQueue.getVisitedCount() 1000) {String url urlQueue.deQueue();if (url null) {break;}Document doc downloader.downloadPage(url);if (doc null) {continue;}SetString urlSet downloader.parsePage(doc, userRequest\\?userRequestshowNoParticipateTasktaskid\\d{1,2}|http://www.cnblogs.com/hujunzheng/(p|default|archive/\\d{4}/\\d{2}/\\d{2}/).*);urlQueue.enQueue(urlSet);downloader.savePage(doc, I:\\博客园-hjzgg, null, userRequest\\?userRequestshowNoParticipateTasktaskid\\d{1,2}|http://www.cnblogs.com/hujunzheng/(p|default|archive/\\d{4}/\\d{2}/\\d{2}/).*);System.out.println(已请求 urlQueue.getVisitedCount() 个页面);}long end System.currentTimeMillis();System.out.println(抓取完成共抓取 urlQueue.getVisitedCount() 到个页面用时 ((end - start) / 1000) s);}
} 注userRequest\\?userRequestshowNoParticipateTasktaskid\\d{1,2} 是本地的网站中网页里的地址当然种子地址也是本地网站 在请求这个地址后会产生地址重定向到博客园地址http://www.cnblogs.com/hujunzheng/并完成相应的下载 1.这是请求超时的情况 2.正常访问或者重定向访问 转载于:https://www.cnblogs.com/hujunzheng/p/4852948.html