1. 如何使用java語言實現一個網頁爬蟲
Java開源Web爬蟲
Heritrix
Heritrix是一個開源,可擴展的web爬蟲項目。Heritrix設計成嚴格按照robots.txt文件的排除指示和META robots標簽。
更多Heritrix信息
WebSPHINX
WebSPHINX是一個Java類包和Web爬蟲的互動式開發環境。Web爬蟲(也叫作機器人或蜘蛛)是可以自動瀏覽與處理Web頁面的程序。WebSPHINX由兩部分組成:爬蟲工作平台和WebSPHINX類包。
更多WebSPHINX信息
WebLech
WebLech是一個功能強大的Web站點下載與鏡像工具。它支持按功能需求來下載web站點並能夠盡可能模仿標准Web瀏覽器的行為。WebLech有一個功能控制台並採用多線程操作。
2. Java網路爬蟲怎麼實現
網路爬蟲是一個自動提取網頁的程序,它為搜索引擎從萬維網上下載網頁,是搜索引擎的重要組成。x0dx0a傳統爬蟲從一個或若干初始網頁的URL開始,獲得初始網頁上的URL,在抓取網頁的過程中,不斷從當前頁面上抽取新的URL放入隊列,直到滿足系統的一定停止條件。對於垂直搜索來說,聚焦爬蟲,即有針對性地爬取特定主題網頁的爬蟲,更為適合。x0dx0ax0dx0a以下是一個使用java實現的簡單爬蟲核心代碼:x0dx0apublic void crawl() throws Throwable { x0dx0a while (continueCrawling()) { x0dx0a CrawlerUrl url = getNextUrl(); //獲取待爬取隊列中的下一個URL x0dx0a if (url != null) { x0dx0a printCrawlInfo(); x0dx0a String content = getContent(url); //獲取URL的文本信息 x0dx0a x0dx0a //聚焦爬蟲只爬取與主題內容相關的網頁,這里採用正則匹配簡單處理 x0dx0a if (isContentRelevant(content, this.regexpSearchPattern)) { x0dx0a saveContent(url, content); //保存網頁至本地 x0dx0a x0dx0a //獲取網頁內容中的鏈接,並放入待爬取隊列中 x0dx0a Collection urlStrings = extractUrls(content, url); x0dx0a addUrlsToUrlQueue(url, urlStrings); x0dx0a } else { x0dx0a System.out.println(url + " is not relevant ignoring ..."); x0dx0a } x0dx0a x0dx0a //延時防止被對方屏蔽 x0dx0a Thread.sleep(this.delayBetweenUrls); x0dx0a } x0dx0a } x0dx0a closeOutputStream(); x0dx0a}x0dx0aprivate CrawlerUrl getNextUrl() throws Throwable { x0dx0a CrawlerUrl nextUrl = null; x0dx0a while ((nextUrl == null) && (!urlQueue.isEmpty())) { x0dx0a CrawlerUrl crawlerUrl = this.urlQueue.remove(); x0dx0a //doWeHavePermissionToVisit:是否有許可權訪問該URL,友好的爬蟲會根據網站提供的"Robot.txt"中配置的規則進行爬取 x0dx0a //isUrlAlreadyVisited:URL是否訪問過,大型的搜索引擎往往採用BloomFilter進行排重,這里簡單使用HashMap x0dx0a //isDepthAcceptable:是否達到指定的深度上限。爬蟲一般採取廣度優先的方式。一些網站會構建爬蟲陷阱(自動生成一些無效鏈接使爬蟲陷入死循環),採用深度限制加以避免 x0dx0a if (doWeHavePermissionToVisit(crawlerUrl) x0dx0a && (!isUrlAlreadyVisited(crawlerUrl)) x0dx0a && isDepthAcceptable(crawlerUrl)) { x0dx0a nextUrl = crawlerUrl; x0dx0a // System.out.println("Next url to be visited is " + nextUrl); x0dx0a } x0dx0a } x0dx0a return nextUrl; x0dx0a}x0dx0aprivate String getContent(CrawlerUrl url) throws Throwable { x0dx0a //HttpClient4.1的調用與之前的方式不同 x0dx0a HttpClient client = new DefaultHttpClient(); x0dx0a HttpGet httpGet = new HttpGet(url.getUrlString()); x0dx0a StringBuffer strBuf = new StringBuffer(); x0dx0a HttpResponse response = client.execute(httpGet); x0dx0a if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) { x0dx0a HttpEntity entity = response.getEntity(); x0dx0a if (entity != null) { x0dx0a BufferedReader reader = new BufferedReader( x0dx0a new InputStreamReader(entity.getContent(), "UTF-8")); x0dx0a String line = null; x0dx0a if (entity.getContentLength() > 0) { x0dx0a strBuf = new StringBuffer((int) entity.getContentLength()); x0dx0a while ((line = reader.readLine()) != null) { x0dx0a strBuf.append(line); x0dx0a } x0dx0a } x0dx0a } x0dx0a if (entity != null) { x0dx0a nsumeContent(); x0dx0a } x0dx0a } x0dx0a //將url標記為已訪問 x0dx0a markUrlAsVisited(url); x0dx0a return strBuf.toString(); x0dx0a}x0dx0apublic static boolean isContentRelevant(String content, x0dx0aPattern regexpPattern) { x0dx0a boolean retValue = false; x0dx0a if (content != null) { x0dx0a //是否符合正則表達式的條件 x0dx0a Matcher m = regexpPattern.matcher(content.toLowerCase()); x0dx0a retValue = m.find(); x0dx0a } x0dx0a return retValue; x0dx0a}x0dx0apublic List extractUrls(String text, CrawlerUrl crawlerUrl) { x0dx0a Map urlMap = new HashMap(); x0dx0a extractHttpUrls(urlMap, text); x0dx0a extractRelativeUrls(urlMap, text, crawlerUrl); x0dx0a return new ArrayList(urlMap.keySet()); x0dx0a} x0dx0aprivate void extractHttpUrls(Map urlMap, String text) { x0dx0a Matcher m = (text); x0dx0a while (m.find()) { x0dx0a String url = m.group(); x0dx0a String[] terms = url.split("a href=\""); x0dx0a for (String term : terms) { x0dx0a // System.out.println("Term = " + term); x0dx0a if (term.startsWith("http")) { x0dx0a int index = term.indexOf("\""); x0dx0a if (index > 0) { x0dx0a term = term.substring(0, index); x0dx0a } x0dx0a urlMap.put(term, term); x0dx0a System.out.println("Hyperlink: " + term); x0dx0a } x0dx0a } x0dx0a } x0dx0a} x0dx0aprivate void extractRelativeUrls(Map urlMap, String text, x0dx0a CrawlerUrl crawlerUrl) { x0dx0a Matcher m = relativeRegexp.matcher(text); x0dx0a URL textURL = crawlerUrl.getURL(); x0dx0a String host = textURL.getHost(); x0dx0a while (m.find()) { x0dx0a String url = m.group(); x0dx0a String[] terms = url.split("a href=\""); x0dx0a for (String term : terms) { x0dx0a if (term.startsWith("/")) { x0dx0a int index = term.indexOf("\""); x0dx0a if (index > 0) { x0dx0a term = term.substring(0, index); x0dx0a } x0dx0a String s = //" + host + term; x0dx0a urlMap.put(s, s); x0dx0a System.out.println("Relative url: " + s); x0dx0a } x0dx0a } x0dx0a } x0dx0a x0dx0a}x0dx0apublic static void main(String[] args) { x0dx0a try { x0dx0a String url = ""; x0dx0a Queue urlQueue = new LinkedList(); x0dx0a String regexp = "java"; x0dx0a urlQueue.add(new CrawlerUrl(url, 0)); x0dx0a NaiveCrawler crawler = new NaiveCrawler(urlQueue, 100, 5, 1000L, x0dx0a regexp); x0dx0a // boolean allowCrawl = crawler.areWeAllowedToVisit(url); x0dx0a // System.out.println("Allowed to crawl: " + url + " " + x0dx0a // allowCrawl); x0dx0a crawler.crawl(); x0dx0a } catch (Throwable t) { x0dx0a System.out.println(t.toString()); x0dx0a t.printStackTrace(); x0dx0a } x0dx0a}
3. java爬蟲抓取指定數據
如何通過Java代碼實現對網頁數據進行指定抓取,我總結了有以下幾個步驟中會使用到Jsoup.Jar包:
1、在工程中導入Jsoup.jar包
2、獲取網址url指定HTML或者文檔指定的body
3、獲取網頁中超鏈接的標題和鏈接
4、獲取指定博客文章的內容
5、獲取網頁中超鏈接的標題和鏈接的結果
4. Java多線程爬蟲實現
一、需求
1.定時抓取固定網站新聞標題、內容、發表時間和來源。
2.程序需要支持分布式、多線程
二、設計
1.網站是固定,但是未來也可能添加新的網站去抓取,每個網站內容節點設計都不一樣,這樣就需要支持動態可配置來新增網站以方便未來的擴展,這樣就需要每次都需要開發介入。
2.網站html節點的結構可能發生變化,所以也要支持提取節點可配置。
3.怎樣支持分布式?暫時最簡單的想法就是:多機器部署程序,還有新搞一台或者部署程序其中一台製作一個定時任務,定時開啟每台機器應該抓取哪個網站,暫時不能支持同一個網站同時可以支持被多台機器同時抓取,這樣會比較麻煩,要用到分布式隊列。所以暫時一個網站同時只會被單台機器抓取。
4.多線程,怎樣多線程?多線程抓取我這邊有兩個實現:
(1)一個線程抓取一個網站,維護一罩拿個自己的url隊列做廣度抓取,同時抓取多個網站。如圖:
(2)多個線程同時抓取不同的網站。如圖:
以上兩飢悶做張辦法其實各有優點,也給有缺點,看我們怎麼取捨了。
方法1:每個線程創建一個自己的隊列,圖中的queue可以不用concurrentQueue,優點:不涉及到控制並發,每個網站一個線程抓取一個網站,抓取完畢即自動回收銷毀線程。控制方便。缺點:線程數不可以擴展,例如當只有3個網站,你最多隻能開3個線程來抓取,不能開更多,有一定的局限性。
方法2:N個線程同時抓取N個網站,線程數和網站數目不掛鉤,優點:線程數可以調整並且和和抓取網站數量無關。3個網站我們可以開4個5個或者10個這個可以根據您的硬體資源進行調整。缺點:需要控制並發,並且要控制什麼時候銷毀線程(thread1空閑,並且queue為空不代表任務可以結束,可能thread2結果還沒返回),當被抓取的網站響應較慢時,會拖慢整個爬蟲進度。
三、實現
抓取方式最終還是選擇了方法二,因為線程數可配置!
使用技術:
jfinal用了之後才發現這東西不適合,但是由於項目進度問題,還是使用了。
maven項目管理
jettyserver
mysql
eclipse開發
項目需要重點攻破的難點:
(1)合理的控制N個線程正常的抓取網站,並且當所有爛衡線程工作都完成了並且需要抓取的隊列為空時,N個線程同時退出銷毀。
(2)不同網站設計節點不一樣,需要通過配置解決各個網站需要抓取的URL和抓取節點內容在html節點的位置。
(3)個性化內容處理,由於html結構設計問題,北大青鳥認為抓取的內容可能有些多餘的html標簽,或者多餘的內容該怎麼處理。
5. java正則如何提取數據(網路爬蟲)
給你幾個代碼示例,獲取其他標簽的內容照著寫就是了:
/**
*
* @param s
* @return 獲得網頁標題
*/
public String getTitle(final String s)
{
String regex;
String title = "";
final List<String> list = new ArrayList<String>();
regex = "<title>.*?</title>";
final Pattern pa = Pattern.compile(regex, Pattern.CANON_EQ);
final Matcher ma = pa.matcher(s);
while (ma.find())
{
list.add(ma.group());
}
for (int i = 0; i < list.size(); i++)
{
title = title + list.get(i);
}
return outTag(title);
}
/**
*
* @param s
* @return 獲得鏈接
*/
public List<String> getLink(final String s)
{
String regex;
final List<String> list = new ArrayList<String>();
regex = "<a[^>]*href=(\"([^\"]*)\"|\'([^\']*)\'|([^\\s>]*))[^>]*>(.*?)</a>";
final Pattern pa = Pattern.compile(regex, Pattern.DOTALL);
final Matcher ma = pa.matcher(s);
while (ma.find())
{
list.add(ma.group());
}
return list;
}
/**
*
* @param s
* @return 獲得腳本代碼
*/
public List<String> getScript(final String s)
{
String regex;
final List<String> list = new ArrayList<String>();
regex = "<script.*?</script>";
final Pattern pa = Pattern.compile(regex, Pattern.DOTALL);
final Matcher ma = pa.matcher(s);
while (ma.find())
{
list.add(ma.group());
}
return list;
}
/**
*
* @param s
* @return 獲得CSS
*/
public List<String> getCSS(final String s)
{
String regex;
final List<String> list = new ArrayList<String>();
regex = "<style.*?</style>";
final Pattern pa = Pattern.compile(regex, Pattern.DOTALL);
final Matcher ma = pa.matcher(s);
while (ma.find())
{
list.add(ma.group());
}
return list;
}
6. 如何java寫/實現網路爬蟲抓取網頁
網路爬蟲是一個自動提取網頁的程序,它為搜索引擎從萬維網上下載網頁,是搜索引擎的重要組成。傳統爬蟲從一個或若干初始網頁的URL開始,獲得初始網頁上的URL,在抓取網頁的過程中,不斷從當前頁面上抽取新的URL放入隊列,直到滿足系統的一定停止條件。
java實現網頁源碼獲取的步驟:
(1)新建URL對象,表示要訪問的網址。如:url=new URL("http://www.sina.com.cn");
(2)建立HTTP連接,返回連接對象urlConnection對象。如:urlConnection = (HttpURLConnection)url.openConnection();
(3)獲取相應HTTP 狀態碼。如responsecode=urlConnection.getResponseCode();
(4)如果HTTP 狀態碼為200,表示成功。從urlConnection對象獲取輸入流對象來獲取請求的網頁源代碼。