java调用百度搜索_Java爬虫怎么调用百度搜索引擎,对关键字的网页爬取?
該樓層疑似違規(guī)已被系統(tǒng)折疊?隱藏此樓查看此樓
package com.wjd.baidukey.crawler; import java.io.ByteArrayInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.URLEncoder; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.TimeZone; import org.apache.poi.poifs.filesystem.DirectoryEntry; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import cn.edu.hfut.dmic.contentextractor.ContentExtractor; import cn.edu.hfut.dmic.webcollector.model.CrawlDatum; import cn.edu.hfut.dmic.webcollector.model.CrawlDatums; import cn.edu.hfut.dmic.webcollector.model.Page; import cn.edu.hfut.dmic.webcollector.plugin.ram.RamCrawler; public class BdiduKeywordCrawler extends RamCrawler{ private Connection connection; private PreparedStatement pstatement; // 連接MySql數(shù)據(jù)庫,用戶名root,密碼mahao String url = "jdbc:mysql://localhost:3306/wjd"; String username = "root"; String password = "mahao"; //保存抽取到的數(shù)據(jù) StringBuilder result = new StringBuilder(); public BdiduKeywordCrawler(String keyword, int maxPageNum) throws Exception { for (int pageNum = 1; pageNum <= maxPageNum; pageNum++) { String url = createUrl(keyword, pageNum); CrawlDatum datum = new CrawlDatum(url) .putMetaData("keyword", keyword) .putMetaData("pageNum", pageNum + "") .putMetaData("pageType", "searchEngine") .putMetaData("depth", "1"); addSeed(datum); } } @Override public void visit(Page page, CrawlDatums next) { String keyword = page.getMetaData("keyword"); String pageType = page.getMetaData("pageType"); int depth = Integer.valueOf(page.getMetaData("depth")); if (pageType.equals("searchEngine")) { int pageNum = Integer.valueOf(page.getMetaData("pageNum")); System.out.println("成功抓取關(guān)鍵詞" + keyword + "的第" + pageNum + "頁搜索結(jié)果"); // || div[class=result-op c-container xpath-log ]>h3>a Elements results = page.select("div[class=result c-container ]>h3>a"); // Elements results1 = page.select("div[class=result-op c-container xpath-log]>h3>a");//,div[id=result-op c-container xpath-log]>h3>a //System.out.println(results1.get(0)); //results.add(results1.get(0)); for (int rank = 0; rank < results.size(); rank++) { Element result = results.get(rank); /* * 我們希望繼續(xù)爬取每條搜索結(jié)果指向的網(wǎng)頁,這里統(tǒng)稱為外鏈。 * 我們希望在訪問外鏈時(shí)仍然能夠知道外鏈處于搜索引擎的第幾頁、第幾條, * 所以將頁號(hào)和排序信息放入后續(xù)的CrawlDatum中,為了能夠區(qū)分外鏈和 * 搜索引擎結(jié)果頁面,我們將其pageType設(shè)置為outlink,這里的值完全由 用戶定義,可以設(shè)置一個(gè)任意的值 * 在經(jīng)典爬蟲中,每個(gè)網(wǎng)頁都有一個(gè)refer信息,表示當(dāng)前網(wǎng)頁的鏈接來源。 * 例如我們首先訪問新浪首頁,然后從新浪首頁中解析出了新的新聞鏈接, * 則這些網(wǎng)頁的refer值都是新浪首頁。WebCollector不直接保存refer值, * 但我們可以通過下面的方式,將refer信息保存在metaData中,達(dá)到同樣的效果。 * 經(jīng)典爬蟲中錨文本的存儲(chǔ)也可以通過下面方式實(shí)現(xiàn)。 * 在一些需求中,希望得到當(dāng)前頁面在遍歷樹中的深度,利用metaData很容易實(shí)現(xiàn) * 這個(gè)功能,在將CrawlDatum添加到next中時(shí),將其depth設(shè)置為當(dāng)前訪問頁面 的depth+1即可。 */ CrawlDatum datum = new CrawlDatum(result.attr("abs:href")) .putMetaData("keyword", keyword) .putMetaData("pageNum", pageNum + "") .putMetaData("rank", rank + "") .putMetaData("pageType", "outlink") .putMetaData("depth", (depth + 1) + "") .putMetaData("refer", page.getUrl()); next.add(datum); } } else if (pageType.equals("outlink")) { /*int pageNum = Integer.valueOf(page.getMetaData("pageNum")); int rank = Integer.valueOf(page.getMetaData("rank")); String refer = page.getMetaData("refer");*/ try { String content = ContentExtractor.getContentByUrl(page.getUrl()); /*String line = String.format( "第%s頁第%s個(gè)結(jié)果:標(biāo)題:%s(%s字節(jié))\tdepth=%s\trefer=%s", pageNum, rank + 1, page.getDoc().title(), content, depth, refer);*/ String line = String.format("標(biāo)題:%s\n來源:%s\n正文:%s", page.getDoc().title(),page.getUrl(),content); HashMap data = new HashMap(); Date currentDate = new java.util.Date(); SimpleDateFormat myFmt = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); TimeZone timeZoneChina = TimeZone.getTimeZone("Asia/Shanghai");// 獲取中國的時(shí)區(qū) myFmt.setTimeZone(timeZoneChina);// 設(shè)置系統(tǒng)時(shí)區(qū) String grabTime = myFmt.format(currentDate);// new Date()為獲取當(dāng)前系統(tǒng)時(shí)間 data.put("title", page.getDoc().title()); data.put("from", page.getUrl()); data.put("content", content); data.put("grabTime", grabTime); //String line = String.format("標(biāo)題:%s\n", page.getDoc().title()); //持久化到word文檔中 //是否為線程安全??? //synchronized(this) { String destFile = "D:\\"+"Result"+keyword+".doc"; result.append(line); //將result寫到doc文件中 write2File(destFile,result.toString()); //添加到數(shù)據(jù)庫中 addResultData(data); //} System.out.println(line); } catch (Exception e) { //e.printStackTrace(); System.out.println("鏈接"+page.getUrl()+"失效"); } } } //將數(shù)據(jù)保存到mysql數(shù)據(jù)庫中 private void addResultData(HashMap data) { String title = data.get("title"); String source_url = data.get("from"); String content = data.get("content").replaceAll("\\?{2,}", "");//去掉字符串中出現(xiàn)的多個(gè)連續(xù)問號(hào)。 //抓取時(shí)間 String grabTime = data.get("grabTime"); /*SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); Date date = null; try { date = format.parse(grabTime); } catch (Exception e) { e.printStackTrace(); }*/ //System.out.println("抓取時(shí)間"+grabTime); try { connection = DriverManager.getConnection(url, username, password); String sql = "INSERT INTO wjd_keyword_search_table(TITLE,GRAP_TIME,CONTENT,SOURCE_URL) VALUES(?,?,?,?)"; String checkSql = "select 1 from wjd_keyword_search_table where TITLE='" + title + "'"; Statement statement = connection.prepareStatement(checkSql); ResultSet result = statement.executeQuery(checkSql); if (!result.next()) { // 如果數(shù)據(jù)庫中不存在該記錄,則添加到數(shù)據(jù)庫中 pstatement = connection.prepareStatement(sql); pstatement.setString(1, title); //pstatement.setString(2, date); pstatement.setString(2,grabTime); pstatement.setString(3, content); pstatement.setString(4, source_url); pstatement.executeUpdate(); } } catch (SQLException e) { e.printStackTrace(); } } /** * 將數(shù)據(jù)持久化到本地doc文件中 * @param destFile * @param line */ private void write2File(String destFile, String line) { try { //doc content ByteArrayInputStream bais = new ByteArrayInputStream(line.getBytes()); POIFSFileSystem fs = new POIFSFileSystem(); DirectoryEntry directory = fs.getRoot(); directory.createDocument("WordDocument", bais); FileOutputStream ostream = new FileOutputStream(destFile); fs.writeFilesystem(ostream); bais.close(); ostream.close(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { String[] keywordsList = {"網(wǎng)絡(luò)爬蟲","搜索引擎"}; int pageToal =5; for (String keyword : keywordsList) { BdiduKeywordCrawler crawler = new BdiduKeywordCrawler(keyword, pageToal); crawler.start(); } } /** * 根據(jù)關(guān)鍵詞和頁號(hào)拼接百度搜索對(duì)應(yīng)的URL */ public static String createUrl(String keyword, int pageNum) throws Exception { int first = (pageNum-1) * 10; keyword = URLEncoder.encode(keyword, "utf-8"); return String.format("https://www.baidu.com/s?wd=%s&pn=%s", keyword, first); } }
總結(jié)
以上是生活随笔為你收集整理的java调用百度搜索_Java爬虫怎么调用百度搜索引擎,对关键字的网页爬取?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html5拍照上传 java_如何使用H
- 下一篇: java中大数开方_Java中的大数运算