search-demo演示了如何利用Java来调用百度搜索和谷歌搜索,更多细节请到github上查看search-demo
自己没搜索引擎,又想要大规模的数据源,怎么办?可以对百度搜索和谷歌搜索善加利用,以小搏大,站在巨人的肩膀上。有很多的应用场景可以很巧妙地借助百度搜索和谷歌搜索来实现,比如网站的新闻采集,比如技术、品牌的新闻跟踪,比如知识库的收集,比如人机问答系统等,我之前做的一个准确率达百分之九十几的人机问答系统的数据源,其中一部分就是充分利用了百度搜索和谷歌搜索。在此演示的技术的基础上,可以容易地扩展到其他的搜索引擎,可以借鉴使用的NekoHTML+XPath或JSoup+CSSPath技术,轻松获取页面的自定义的内容。
实现方式一:NekoHTML+XPath
- package org.apdplat.demo.search;
- import java.io.BufferedReader;
- import java.io.ByteArrayInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.UnsupportedEncodingException;
- import java.net.URL;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.cyberneko.html.parsers.DOMParser;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.w3c.dom.Document;
- import org.w3c.dom.Node;
- import org.w3c.dom.NodeList;
- import org.xml.sax.InputSource;
- import com.sun.org.apache.xpath.internal.XPathAPI;
- import javax.xml.transform.TransformerException;
- import org.w3c.dom.DOMException;
- import org.xml.sax.SAXException;
- public class NekoHTMLBaiduSearcher implements Searcher{
- private static final Logger LOG = LoggerFactory.getLogger(NekoHTMLBaiduSearcher.class);
- public List<String> parse(String url, String xpathExpression) {
- InputStream in = null;
- try {
- in = new URL(url).openStream();
- return parse(in, xpathExpression);
- } catch (Exception e) {
- LOG.error("错误", e);
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (IOException e) {
- LOG.error("错误", e);
- }
- }
- }
- return null;
- }
- public List<String> parse(InputStream in, String xpathExpression) {
- return parse(in, xpathExpression, "UTF-8");
- }
- public List<Map<String, String>> parseMore(InputStream in, String xpathExpression) {
- return parseMore(in, xpathExpression, "UTF-8");
- }
- public List<Map<String, String>> parseMore(InputStream in, String xpathExpression, String encoding) {
- DOMParser parser = new DOMParser();
- List<Map<String, String>> list = new ArrayList<>();
- try {
- // 设置网页的默认编码
- parser.setProperty(
- "http://cyberneko.org/html/properties/default-encoding",
- encoding);
- /*
- * The Xerces HTML DOM implementation does not support namespaces
- * and cannot represent XHTML documents with namespace information.
- * Therefore, in order to use the default HTML DOM implementation
- * with NekoHTML's DOMParser to parse XHTML documents, you must turn
- * off namespace processing.
- */
- parser.setFeature("http://xml.org/sax/features/namespaces", false);
- parser.parse(new InputSource(new BufferedReader(new InputStreamReader(in, encoding))));
- Document doc = parser.getDocument();
- NodeList products = XPathAPI.selectNodeList(doc, xpathExpression.toUpperCase());
- for (int i = 0; i < products.getLength(); i++) {
- Node node = products.item(i);
- String title = node.getTextContent();
- Map<String, String> map = new HashMap<>();
- map.put("title", title);
- try {
- String href = node.getAttributes().getNamedItem("href").getTextContent();
- map.put("href", href);
- } catch (Exception e) {
- LOG.error("提取链接失败",e);
- }
- list.add(map);
- }
- } catch (SAXException | IOException | TransformerException | DOMException e) {
- LOG.error("错误", e);
- }
- return list;
- }
- public List<String> parse(InputStream in, String xpathExpression, String encoding) {
- DOMParser parser = new DOMParser();
- List<String> list = new ArrayList<>();
- try {
- // 设置网页的默认编码
- parser.setProperty(
- "http://cyberneko.org/html/properties/default-encoding",
- encoding);
- /*
- * The Xerces HTML DOM implementation does not support namespaces
- * and cannot represent XHTML documents with namespace information.
- * Therefore, in order to use the default HTML DOM implementation
- * with NekoHTML's DOMParser to parse XHTML documents, you must turn
- * off namespace processing.
- */
- parser.setFeature("http://xml.org/sax/features/namespaces", false);
- parser.parse(new InputSource(new BufferedReader(new InputStreamReader(in, encoding))));
- Document doc = parser.getDocument();
- NodeList products = XPathAPI.selectNodeList(doc, xpathExpression.toUpperCase());
- for (int i = 0; i < products.getLength(); i++) {
- Node node = products.item(i);
- list.add(node.getTextContent());
- }
- } catch (SAXException | IOException | TransformerException | DOMException e) {
- LOG.error("错误", e);
- }
- return list;
- }
- @Override
- public List<Webpage> search(String url) {
- InputStream in = null;
- try {
- in = new URL(url).openStream();
- return search(in);
- } catch (Exception e) {
- LOG.error("错误", e);
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (IOException e) {
- LOG.error("错误", e);
- }
- }
- }
- return null;
- }
- public List<Webpage> search(InputStream in) {
- //保证只读一次
- byte[] datas = Tools.readAll(in);
- if (LOG.isDebugEnabled()) {
- try {
- LOG.debug("内容:" + new String(datas, "UTF-8"));
- } catch (UnsupportedEncodingException e) {
- LOG.error("错误", e);
- }
- }
- in = new ByteArrayInputStream(datas);
- String totalXpathExpression = "//html/body/div/div/div/div[3]/p/span";
- List<String> totals = parse(in, totalXpathExpression);
- int total;
- int len = 10;
- if (totals != null && totals.size() == 1) {
- String str = totals.get(0);
- int start = 10;
- if (str.indexOf("约") != -1) {
- start = 11;
- }
- total = Integer.parseInt(str.substring(start).replace(",", "").replace("个", ""));
- LOG.info("搜索结果数:" + total);
- } else {
- return null;
- }
- if (total < 1) {
- return null;
- }
- if (total < 10) {
- len = total;
- }
- List<Webpage> webpages = new ArrayList<>();
- for (int i = 0; i < len; i++) {
- String content = "";
- String url = "";
- String titleXpathExpression = "//html/body/div/div/div/div[3]/div[2]/table[" + (i + 1) + "]/tbody/tr/td/h3/a";
- String summaryXpathExpression = "//html/body/div/div/div/div[3]/div[2]/table[" + (i + 1) + "]/tbody/tr/td/div[1]";
- LOG.debug("titleXpathExpression:" + titleXpathExpression);
- LOG.debug("summaryXpathExpression:" + summaryXpathExpression);
- //重新构造输入流
- in = new ByteArrayInputStream(datas);
- List<String> titles = parse(in, titleXpathExpression);
- //重新构造输入流
- in = new ByteArrayInputStream(datas);
- List<Map<String, String>> titleWithHrefs = parseMore(in, titleXpathExpression);
- for (Map<String, String> titleWithHref : titleWithHrefs) {
- String title = titleWithHref.get("title");
- String href = titleWithHref.get("href");
- LOG.debug(title + " " + titleWithHref.get("href"));
- if (href != null) {
- content = Tools.getHTMLContent(href);
- url = href;
- } else {
- LOG.info("页面正确提取失败");
- }
- }
- //重新构造输入流
- in = new ByteArrayInputStream(datas);
- List<String> summaries = parse(in, summaryXpathExpression);
- //处理百度知道1
- if (titles != null && titles.size() == 1 && (summaries == null || summaries.isEmpty())) {
- //重新构造输入流
- in = new ByteArrayInputStream(datas);
- String baiduZhidao1XpathExpression = "//html/body/div/div/div/div[3]/div[2]/table[" + (i + 1) + "]/tbody/tr/td/font[2]/div/div/p[2]";
- LOG.debug("baiduZhidao1XpathExpression:" + baiduZhidao1XpathExpression);
- summaries = parse(in, baiduZhidao1XpathExpression);
- }
- //处理百度知道2
- if (titles != null && titles.size() == 1 && (summaries == null || summaries.isEmpty())) {
- //重新构造输入流
- in = new ByteArrayInputStream(datas);
- String baiduZhidao2XpathExpression = "//html/body/div/div/div/div[3]/div[2]/table[" + (i + 1) + "]/tbody/tr/td/font[2]";
- LOG.debug("baiduZhidao2XpathExpression:" + baiduZhidao2XpathExpression);
- summaries = parse(in, baiduZhidao2XpathExpression);
- }
- //处理百度文库
- if (titles != null && titles.size() == 1 && (summaries == null || summaries.isEmpty())) {
- //重新构造输入流
- in = new ByteArrayInputStream(datas);
- String baiduWenkuXpathExpression = "//html/body/div/div/div/div[3]/div[2]/table[" + (i + 1) + "]/tbody/tr/td/font[1]";
- LOG.debug("baiduWenkuXpathExpression:" + baiduWenkuXpathExpression);
- summaries = parse(in, baiduWenkuXpathExpression);
- }
- if (titles != null && titles.size() == 1 && summaries != null && summaries.size() == 1) {
- Webpage webpage = new Webpage();
- webpage.setTitle(titles.get(0));
- webpage.setUrl(url);
- webpage.setSummary(summaries.get(0));
- webpage.setContent(content);
- webpages.add(webpage);
- } else {
- LOG.error("获取搜索结果列表项出错:" + titles + " - " + summaries);
- }
- }
- if(webpages.size() < 10){
- //处理百度百科
- String titleXpathExpression = "//html/body/div/div/div/div[3]/div[2]/div/h3/a";
- String summaryXpathExpression = "//html/body/div/div/div/div[3]/div[2]/div/div/p";
- LOG.debug("处理百度百科 titleXpathExpression:" + titleXpathExpression);
- LOG.debug("处理百度百科 summaryXpathExpression:" + summaryXpathExpression);
- //重新构造输入流
- in = new ByteArrayInputStream(datas);
- List<String> titles = parse(in, titleXpathExpression);
- //重新构造输入流
- in = new ByteArrayInputStream(datas);
- List<Map<String, String>> titleWithHrefs = parseMore(in, titleXpathExpression);
- String content = "";
- String url = "";
- for (Map<String, String> titleWithHref : titleWithHrefs) {
- String title = titleWithHref.get("title");
- String href = titleWithHref.get("href");
- LOG.debug(title + " " + titleWithHref.get("href"));
- if (href != null) {
- content = Tools.getHTMLContent(href);
- url = href;
- } else {
- LOG.info("页面正确提取失败");
- }
- }
- //重新构造输入流
- in = new ByteArrayInputStream(datas);
- List<String> summaries = parse(in, summaryXpathExpression);
- if (titles != null && titles.size() == 1 && summaries != null && summaries.size() == 1) {
- Webpage webpage = new Webpage();
- webpage.setTitle(titles.get(0));
- webpage.setUrl(url);
- webpage.setSummary(summaries.get(0));
- webpage.setContent(content);
- webpages.add(webpage);
- } else {
- LOG.error("获取搜索结果列表项出错:" + titles + " - " + summaries);
- }
- }
- if (webpages.isEmpty()) {
- return null;
- }
- return webpages;
- }
- public static void main(String[] args) {
- String url = "http://www.baidu.com/s?pn=0&wd=杨尚川";
- Searcher searcher = new NekoHTMLBaiduSearcher();
- List<Webpage> webpages = searcher.search(url);
- if (webpages != null) {
- int i = 1;
- for (Webpage webpage : webpages) {
- LOG.info("搜索结果 " + (i++) + " :");
- LOG.info("标题:" + webpage.getTitle());
- LOG.info("URL:" + webpage.getUrl());
- LOG.info("摘要:" + webpage.getSummary());
- LOG.info("正文:" + webpage.getContent());
- LOG.info("");
- }
- } else {
- LOG.error("没有搜索到结果");
- }
- }
- }
实现方式二:JSoup+CSSPath
- package org.apdplat.demo.search;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.List;
- import org.jsoup.Jsoup;
- import org.jsoup.nodes.Document;
- import org.jsoup.nodes.Element;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- public class JSoupBaiduSearcher implements Searcher{
- private static final Logger LOG = LoggerFactory.getLogger(JSoupBaiduSearcher.class);
- @Override
- public List<Webpage> search(String url) {
- List<Webpage> webpages = new ArrayList<>();
- try {
- Document document = Jsoup.connect(url).get();
- String cssQuery = "html body div#out div#in div#wrapper div#container.container_s p#page span.nums";
- LOG.debug("total cssQuery: " + cssQuery);
- Element totalElement = document.select(cssQuery).first();
- String totalText = totalElement.text();
- LOG.info("搜索结果:" + totalText);
- int start = 10;
- if (totalText.indexOf("约") != -1) {
- start = 11;
- }
- int total = Integer.parseInt(totalText.substring(start).replace(",", "").replace("个", ""));
- LOG.info("搜索结果数:" + total);
- int len = 10;
- if (total < 1) {
- return null;
- }
- if (total < 10) {
- len = total;
- }
- for (int i = 0; i < len; i++) {
- String titleCssQuery = "html body div#out div#in div#wrapper div#container.container_s div#content_left table#" + (i + 1) + ".result tbody tr td.c-default h3.t a";
- String summaryCssQuery = "html body div#out div#in div#wrapper div#container.container_s div#content_left table#" + (i + 1) + ".result tbody tr td.c-default div.c-abstract";
- LOG.debug("titleCssQuery:" + titleCssQuery);
- LOG.debug("summaryCssQuery:" + summaryCssQuery);
- Element titleElement = document.select(titleCssQuery).first();
- String href = "";
- String titleText = "";
- if(titleElement != null){
- titleText = titleElement.text();
- href = titleElement.attr("href");
- }else{
- //处理百度百科
- titleCssQuery = "html body div#out div#in div#wrapper div#container.container_s div#content_left div#1.result-op h3.t a";
- summaryCssQuery = "html body div#out div#in div#wrapper div#container.container_s div#content_left div#1.result-op div p";
- LOG.debug("处理百度百科 titleCssQuery:" + titleCssQuery);
- LOG.debug("处理百度百科 summaryCssQuery:" + summaryCssQuery);
- titleElement = document.select(titleCssQuery).first();
- if(titleElement != null){
- titleText = titleElement.text();
- href = titleElement.attr("href");
- }
- }
- LOG.debug(titleText);
- Element summaryElement = document.select(summaryCssQuery).first();
- //处理百度知道
- if(summaryElement == null){
- summaryCssQuery = summaryCssQuery.replace("div.c-abstract","font");
- LOG.debug("处理百度知道 summaryCssQuery:" + summaryCssQuery);
- summaryElement = document.select(summaryCssQuery).first();
- }
- String summaryText = "";
- if(summaryElement != null){
- summaryText = summaryElement.text();
- }
- LOG.debug(summaryText);
- if (titleText != null && !"".equals(titleText.trim()) && summaryText != null && !"".equals(summaryText.trim())) {
- Webpage webpage = new Webpage();
- webpage.setTitle(titleText);
- webpage.setUrl(href);
- webpage.setSummary(summaryText);
- if (href != null) {
- String content = Tools.getHTMLContent(href);
- webpage.setContent(content);
- } else {
- LOG.info("页面正确提取失败");
- }
- webpages.add(webpage);
- } else {
- LOG.error("获取搜索结果列表项出错:" + titleText + " - " + summaryText);
- }
- }
- } catch (IOException ex) {
- LOG.error("搜索出错",ex);
- }
- return webpages;
- }
- public static void main(String[] args) {
- String url = "http://www.baidu.com/s?pn=0&wd=杨尚川";
- Searcher searcher = new JSoupBaiduSearcher();
- List<Webpage> webpages = searcher.search(url);
- if (webpages != null) {
- int i = 1;
- for (Webpage webpage : webpages) {
- LOG.info("搜索结果 " + (i++) + " :");
- LOG.info("标题:" + webpage.getTitle());
- LOG.info("URL:" + webpage.getUrl());
- LOG.info("摘要:" + webpage.getSummary());
- LOG.info("正文:" + webpage.getContent());
- LOG.info("");
- }
- } else {
- LOG.error("没有搜索到结果");
- }
- }
- }
相关推荐
在IT行业中,与“百度搜索接口java后台”相关的知识点涵盖了搜索引擎接口的使用、Java编程语言以及后台服务开发。本文将详细解析这些关键概念,并提供如何使用Java后台来对接百度搜索接口的方法。 首先,我们需要...
3. **百度搜索API**:虽然没有直接提及,但获取百度搜索数据可能需要使用百度的公开API。例如,百度开放搜索API或者百度统计API,但请注意,这些服务可能需要申请API密钥,并且有使用限制和费用。 4. **SO-PMI算法*...
在Java中,我们可以调用百度的比对接口,传入两张人脸的特征向量进行比较。 4. **人脸属性分析**: 百度的人脸API还支持分析人脸的属性,如年龄、性别、表情等,这对于某些应用场景非常有用,如个性化推荐或情绪...
4. **Web服务调用**:理解如何使用API密钥、请求参数和签名机制是调用百度地图API的关键。开发者需要根据API文档,构造正确的请求URL,添加必要的参数,如起点、终点、方式(驾车、步行、骑行等),并计算安全签名。...
这个过程会涉及调用百度API的人脸搜索接口。 **API密钥**:在使用任何第三方API时,都需要一个唯一的密钥来验证你的应用程序。在百度API中,你需要在开发者控制台注册并创建项目,然后获取API密钥和密钥 secrect。 ...
在这个项目中,我们将讨论如何使用JSONP调用百度的API来实现搜索关键字的智能提示,就像百度搜索框那样。 标题中的“使用jsonp调用百度的js实现搜索关键字的智能提示”指的是通过JSONP技术与百度的API接口进行交互...
本示例是开发者通过一周的努力整理出的全面调用百度地图API的Demo,旨在帮助开发者省去独立探索的困扰。 首先,我们要了解百度地图SDK。百度地图SDK为Android应用提供了强大的地图服务,包括基本地图展示、地图图层...
5. 实现定位功能,通过调用百度地图API的定位服务获取当前位置信息。 6. 开展搜索功能,可以利用百度地图的地理编码和反地理编码服务,将地址转换为经纬度坐标,或者反之。 在"FindLocation-master"这个文件夹中,...
本人原创测试了百度,搜狗,360搜索都可以获取重定向后的真实地址,直接运行就可以,也可以根据自己项目具体修改功能。java使用HttpURLConnection获取百度搜狗360搜索链接重定向真实目标链接地址url。
在本项目中,"调用百度人脸识别API进行登录.zip"是一个使用Java EE技术栈实现的登录系统,它集成并调用了百度的人脸识别API来增强安全性。以下将详细阐述涉及的关键知识点: 1. **百度人脸识别API**:百度提供的...
在这个"java百度搜索(jquery ajax java)"的项目中,我们可以探讨这些技术如何协同工作。 首先,jQuery是一个流行的JavaScript库,它简化了DOM操作、事件处理、动画以及Ajax交互等任务。jQuery的使用可以极大地提高...
利用元搜索下在百度 doc 文件。示例 利用httpclient 模拟像百度发请求
标题中的“java桌面应用程序(读取百度热搜关键词)”表明这是一个使用Java编程语言开发的桌面应用,其主要功能是获取并展示百度新闻的热搜关键词。这个程序可能利用网络请求技术来抓取百度新闻的实时热点数据,特别...
在Java编程领域,结合百度地图API来搜索附近的美食是一项实用且常见的任务,尤其适用于开发本地生活服务类的应用程序。这个项目或教程可能涉及到以下几个关键知识点: 1. **百度地图API**:百度地图提供了丰富的Web...
在这个过程中,我们需要调用百度AI的特征提取API,将捕获的人脸图像转换为一组特征向量,然后将这些特征存储到数据库或服务器上,以备后续的人脸搜索使用。 5. **人脸搜索**: 在人脸搜索阶段,我们同样调用人脸...
在IT领域,构建一个搜索引擎是复杂且技术性强的...总的来说,"仿百度搜索功能附带数据库 java+jsp"项目是一个结合了前端交互、后端处理和数据库操作的综合实践,可以帮助开发者提升对Java Web应用开发的理解和技能。
在本项目中,开发人员利用DWR框架模拟了百度搜索引擎的工作流程,用户可以在前端输入关键词,然后通过DWR调用后台Java服务进行搜索,返回结果并在页面上动态展示。这种方式极大地提高了用户体验,使得搜索操作更加...
【标题】"仿百度搜索-java源码"是一个项目,它实现了与百度搜索类似的用户体验,特别是输入关键词时的自动匹配功能。这个项目的核心是利用Java语言编写后端逻辑,并结合前端技术如Bootstrap、jQuery以及autocomplete...
4. **调用人脸识别接口**:现在你可以调用百度提供的各种人脸识别接口了。例如,进行人脸检测可以使用`detect`方法,人脸对比可以使用`compare`方法,人脸搜索则使用`search`方法。每个方法都需要传入人脸图片的Base...
1. 文件读取与转换:使用Java的`File`类读取PDF文件,并通过调用`PDF2SWF`命令行接口执行转换操作。 2. 转换参数设置:可能包含调整转换质量、页面范围、缩放比例等参数的逻辑。 3. 错误处理:对转换过程中可能出现...