<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ##一、寫在前面 **(本專欄分為“java版微博爬蟲”和“python版網絡爬蟲”兩個項目,系列里所有文章將基于這兩個項目講解,項目完整源碼已經整理到我的Github,有興趣的可以去看下,鏈接地址在文末。)** 網絡爬蟲根據需求的不同也分不同種類: 1.一種是爬取網頁鏈接,通過url鏈接得到這個html頁面中指定的鏈接,把這些鏈接存儲起來,再依次以這些鏈接為源,再次爬取連接指向html頁面中的鏈接……如此層層遞歸下去,常用的方法是廣度優先或者深度優先,根據爬取層次需求不同而選擇不同的方法達到最優效果,爬蟲的效率優化是一個關鍵。 搜索引擎的第一個步驟就是通過爬蟲得到需要索引的鏈接或數據,存放于數據庫,然后對這些數據建立索引,然后定義查詢語句,解析查詢語句并利用檢索器對數據庫里的數據進行檢索。 2.一種是爬取數據信息,如文本信息、圖片信息等,有時需要做數據分析,通過某種手段來獲取數據樣本以供后續分析,常用的方法是爬蟲獲取指定數據樣本或利用現有的公共數據庫。本文的微博爬蟲屬于第二種類,根據自定義搜索關鍵字爬取微博信息數據。 對于網絡爬蟲原理,其實并不復雜。基本思路是:由關鍵字指定的url把所有相關的html頁面全抓下來(html即為字符串),然后解析html文本(通常是正則表達式或者現成工具包如jsoup),提取微博文本信息,然后把文本信息存儲起來。 重點在于對html頁面源碼結構的分析,不同的html需要不同的解析方法;還有就是長時間爬取可能對IP有影響,有時需要獲取代理IP,甚至需要偽裝瀏覽器爬取。 對于微博,通常情況下是必須登錄才能看到微博信息數據(比如騰訊微博),但是有的微博有搜索機制,在非登錄的情況下可以直接通過**搜索話題**來查找相關信息(如新浪微博、網易微博)。考慮到某些反爬蟲機制,如果一個賬號總是爬取信息可能會有些影響(比如被封號),所以本文采用的爬蟲都是非登錄、直接進入微博搜索頁面爬取。這里關鍵是初始url地址。 ##二、網頁分析 舉個例子,對于有搜索機制的微博,如新浪微博和網易微博:(這里尤其要注意地址及參數!) 新浪微博搜索話題地址:http://s.weibo.com/weibo/蘋果手機&nodup=1&page=50 網易微博搜索話題地址:http://t.163.com/tag/蘋果手機 分別來看下網頁截圖和對應網頁源碼: (1) 新浪微博: ![](https://box.kancloud.cn/2016-02-18_56c5641aaf271.jpg) ![](https://box.kancloud.cn/2016-02-18_56c5641ad33bd.jpg) (2) 網易微博: ![](https://box.kancloud.cn/2016-02-18_56c5641b01f02.jpg) ![](https://box.kancloud.cn/2016-02-18_56c5641b20d29.jpg) 我們需要做的就是把微博的文本提取出來,這里有些特征信息:根據關鍵字搜到的微博,其關鍵字會被標紅,在html源碼里有體現,分別查看兩個網頁的源代碼。 可以看到,新浪微博的源碼全部為html標簽,為了反爬蟲故意將源碼混亂,并且漢字也做了處理,顯示漢字的utf-8編碼而不是直接顯示漢字,不太好找,這里就需要查找紅色字體color:red的部分,其中<span style=\”color:red;\”>\u82f9\u679c\u624b\u673a<\span>中間夾著的哪些utf8編碼其實就是關鍵字“蘋果手機”。后面的那些utf8編碼就是本條微博的文本內容。 而網易微博在這方面就要看起來容易許多,至少html里直接顯示的是漢字,比較好找,而且微博文本部分其實是以json格式體現的,直接解析json就可以提取文本數據了,當然也可以直接用正則。 ##三、爬取微博 這里先寫個簡單的爬蟲,原理都差不多,就拿網易微博為例,先說下爬蟲程序需要用到的工具包: httpclient-4.3.1.jar? -------建立HTTP鏈接,用于從url獲取html httpcore-4.3.jar httpmime-4.3.1.jar httpclient-cache-4.3.1.jar fluent-hc-4.3.1.jar fastjson-1.1.41.jar?? ------解析json的工具包 jsoup-1.7.3.jar? ????-------解析xml,html的工具包 dom4j-1.6.1.jar ????-------讀寫xml的工具包 commons-lang-2.1.jar commons-logging-1.2.jar commons-codec-1.8.jar 總體思路: 1. getHTML()方法:從url得到html字符串。 這里有兩個關鍵點: (1) 設置用戶cookie策略,屏蔽掉cookie rejected的報錯,當然可以不設置,直接用默認的client,即是CloseableHttpClient client = HttpClients.createDefault();創建的客戶端,但是會報錯;設置cookie的代碼如下: ~~~ CookieSpecProvider cookieSpecProvider = new CookieSpecProvider(){ public CookieSpec create(HttpContext context){ return new BrowserCompatSpec(){ @Override public void validate(Cookie cookie, CookieOrigin origin) throws MalformedCookieException { //Oh, I am easy; } }; } }; Registry<CookieSpecProvider> r = RegistryBuilder .<CookieSpecProvider> create() .register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory()) .register(CookieSpecs.BROWSER_COMPATIBILITY, new BrowserCompatSpecFactory()) .register("easy", cookieSpecProvider) .build(); ~~~ (2) 設置socket超時socketTimeout和連接超時connectTimeout,這很關鍵,如果不設置的話,當網絡不好的情況下,某次請求沒有及時得到響應,程序可能會卡死。但是設置連接超時,超時之后再自動重連就可以避免這個問題。代碼如下: ~~~ RequestConfig requestConfig = RequestConfig.custom() .setCookieSpec("easy") .setSocketTimeout(5000) //設置socket超時時間 .setConnectTimeout(5000) //設置connect超時時間 .build(); ~~~ 2.isExitHTML()方法: 判斷html是否合法(有效html,有微博內容的),有時候會出現頁面不存在的情況,是因為該關鍵字沒有微博信息,這是頁面有提示:“沒有找到相關的微博呢,換個關鍵詞試試吧!”如下圖; ![](https://box.kancloud.cn/2016-02-18_56c5641b3a7e5.jpg) 3.writeWeibo2txt()方法: 正則解析(這里主要解析微博文本內容content、用戶id、發文時間prettyTime),得到微博文本數據:控制臺輸出、寫到txt文件; (這里沒有用jsoup去解析html,直接用的正則,有時間后面再寫jsoup解析html的,比正則方便,當然對正則表達式這個工具掌握很熟練的朋友可以忽略……) 我的博客里另外有一篇正則教程完全總結,可以去看下:[正則表達式總結](http://blog.csdn.net/dianacody/article/details/39122645) 本來網易微博的源代碼里嵌入了json元素,前面的html標簽的都不是微博文本數據,在這個標簽后面??????? <scriptid="data_searchTweet" type="application/json">才是json格式包括的微博文本,本來打算先把json串用正則匹配出來,后來發現,直接匹配關鍵字豈不更好?但這里要注意的是匹配的時候可能會有很多換行符之類的東西,我這里只匹配了三個field,正則表達式"id":\s"\d{19}",(\n*?)|(\s*?)"content":\s".*?",(\n*?)|(\s*?)"prettyTime":\s".*?" 順便推薦一個檢測正則的工具:[http://tool.oschina.net/regex?optionGlobl=global](http://tool.oschina.net/regex?optionGlobl=global) 把源碼貼上來吧: ~~~ /** * @note 1.根據搜索關鍵詞從指定url得到相應的html頁面,并驗證其合法性; * 2.得到微博樣本:寫到txt文件里 * * @author DianaCody * @since 2014-09-26 15:08 * */ import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.regex.Pattern; import java.util.regex.Matcher; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.config.CookieSpecs; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.cookie.Cookie; import org.apache.http.cookie.CookieOrigin; import org.apache.http.cookie.CookieSpec; import org.apache.http.cookie.CookieSpecProvider; import org.apache.http.cookie.MalformedCookieException; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.cookie.BestMatchSpecFactory; import org.apache.http.impl.cookie.BrowserCompatSpec; import org.apache.http.impl.cookie.BrowserCompatSpecFactory; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; public class Weibo163 { private String getHTML(String url) throws URISyntaxException, ClientProtocolException, IOException { //采用用戶自定義cookie策略,不顯示cookie rejected的報錯 CookieSpecProvider cookieSpecProvider = new CookieSpecProvider(){ public CookieSpec create(HttpContext context){ return new BrowserCompatSpec(){ @Override public void validate(Cookie cookie, CookieOrigin origin) throws MalformedCookieException { } }; } }; Registry<CookieSpecProvider> r = RegistryBuilder .<CookieSpecProvider> create() .register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory()) .register(CookieSpecs.BROWSER_COMPATIBILITY, new BrowserCompatSpecFactory()) .register("cookie", cookieSpecProvider) .build(); RequestConfig requestConfig = RequestConfig.custom() .setCookieSpec("cookie") .setSocketTimeout(5000) //設置socket超時時間 .setConnectTimeout(5000) //設置connect超時時間 .build(); CloseableHttpClient httpClient = HttpClients.custom() .setDefaultCookieSpecRegistry(r) .setDefaultRequestConfig(requestConfig) .build(); HttpGet httpGet = new HttpGet(url); httpGet.setConfig(requestConfig); String html = "html獲取失敗"; //用于驗證是否取到正常的html try{ CloseableHttpResponse response = httpClient.execute(httpGet); html = EntityUtils.toString(response.getEntity()); //System.out.println(html); //打印返回的html } catch (IOException e) { e.printStackTrace(); } return html; } private boolean isExistHTML(String html) throws InterruptedException { boolean isExist = false; Pattern pNoResult = Pattern.compile("\\\\u6ca1\\\\u6709\\\\u627e\\\\u5230\\\\u76f8" + "\\\\u5173\\\\u7684\\\\u5fae\\\\u535a\\\\u5462\\\\uff0c\\\\u6362\\\\u4e2a" + "\\\\u5173\\\\u952e\\\\u8bcd\\\\u8bd5\\\\u5427\\\\uff01"); //沒有找到相關的微博呢,換個關鍵詞試試吧!(html頁面上的信息) Matcher mNoResult = pNoResult.matcher(html); if(!mNoResult.find()) { isExist = true; } return isExist; } private void writeWeibo2txt(String html, String savePath) throws IOException { File htmltxt = new File(savePath); //新建一個txt文件用于存放爬取的結果信息 FileWriter fw = new FileWriter(htmltxt); BufferedWriter bw = new BufferedWriter(fw); //regex-----"id":\s"\d{19}",(\n*?)|(\s*?)"content":\s".*?",(\n*?)|(\s*?)"prettyTime":\s".*?" Pattern p = Pattern.compile("\"id\":\\s\"\\d{19}\",(\\n*?)|(\\s*?)\"content\":\\s\".*?\",(\\n*?)|(\\s*?)\"prettyTime\":\\s\".*?\""); Matcher m = p.matcher(html); while(m.find()) { System.out.println(m.group()); bw.write(m.group()); } bw.close(); } public static void main(String[] args) throws IOException, URISyntaxException, InterruptedException { Weibo163 crawler = new Weibo163(); String searchword = "iPad"; //搜索關鍵字為"iPad"的微博html頁面 String html = crawler.getHTML("http://t.163.com/tag/"+searchword); String savePath = "e:/weibo/html.txt"; //輸出到txt文件的存放路徑 if(html != "html獲取失敗") { if(crawler.isExistHTML(html)) { System.out.println(html); crawler.writeWeibo2txt(html, savePath); } } //Pattern p = Pattern.compile("<script id=\"data_searchTweet\" type=\"application/json\">.+?<\script>"); //<script id="data_searchTweet" type="application/json">.*?<\script> //Matcher m = p.matcher(html); //html = crawler.getHTML("http://s.weibo.com/weibo/"+searchword+"&nodup=1&page="+1); //System.out.println(html); } } ~~~ 程序運行截圖: ![](https://box.kancloud.cn/2016-02-18_56c5641b56853.jpg) ![](https://box.kancloud.cn/2016-02-18_56c5641b7fc74.jpg) 該java爬蟲項目源碼github地址:[https://github.com/DianaCody/Spider_SinaTweetCrawler_java](https://github.com/DianaCody/Spider_SinaTweetCrawler_java)。 原創文章,轉載請注明出處:[http://blog.csdn.net/dianacody/article/details/39584977](http://blog.csdn.net/dianacody/article/details/39584977) **另外一個系列對爬蟲的整理筆記**:[http://www.crifan.com/files/doc/docbook/web_scrape_emulate_login/release/html/web_scrape_emulate_login.html](http://www.crifan.com/files/doc/docbook/web_scrape_emulate_login/release/html/web_scrape_emulate_login.html)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看