Jsoup学习总结

雨点打透心脏的1/2处 2021-11-11 08:22 426阅读 0赞

有两个推荐网址:

http://www.open-open.com/jsoup/

http://www.iteye.com/topic/1010581

这两个队jsoup简单使用做了很好的指导

我只提出比较实用的例子:

当我们读取某些网址被屏蔽返回505 时可以尝试用一下代码

  1. // 读取URL
  2. public static Document readUrlFistT(String url) {
  3. Document doc = null;
  4. try {
  5. doc = Jsoup.connect(url).timeout(60 * 1000).userAgent(
  6. "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)")
  7. .followRedirects(true).ignoreHttpErrors(true).post();
  8. } catch (IOException e) {
  9. e.printStackTrace();
  10. if ((e instanceof UnknownHostException)
  11. || (e instanceof SocketTimeoutException)) {
  12. doc = readUrlFistT(url);
  13. }
  14. }
  15. return doc;
  16. }

  也可以用下面的代码

  1. public static Document readUrlFist(String url) {
  2. Document doc = null;
  3. Connection conn = Jsoup.connect(url);
  4. conn
  5. .header(
  6. "User-Agent",
  7. "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2 Googlebot/2.1");
  8. try {
  9. doc = conn.timeout(200 * 1000).get();
  10. } catch (IOException e) {
  11. e.printStackTrace();
  12. if ((e instanceof UnknownHostException)
  13. || (e instanceof SocketTimeoutException)) {
  14. doc = readUrlFist(url);
  15. }
  16. }
  17. return doc;
  18. }

  个人推荐第二个,遇到解析不出来的两个换着用

还有一种情况想知道自己在的兄弟节点中的位置时候可以用siblingElements

这个比elementSiblingIndex()准确点,不过有的时候也不是很准确

下面贴一段我曾经做过的练习:如果你对某个网站做过详细的抓取后,jsoup对于你来说就是小菜了。

从不熟到应用灵活,个人喜好用select 语句,语句简单实用

  1. package com.xinsearch.test;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.Iterator;
  5. import java.util.List;
  6. import java.util.Map;
  7. import java.util.Set;
  8. import org.jsoup.nodes.Document;
  9. import org.jsoup.nodes.Element;
  10. import org.jsoup.select.Elements;
  11. import com.xinsearch.entity.Url;
  12. import com.xinsearch.util.TaoUtil;
  13. public class WedSeven extends TaoUtil {
  14. public static String title = "";
  15. public static Element bestFather = null;
  16. public static List<Url> urls = new ArrayList<Url>();
  17. public static void main(String[] args) {
  18. String url = "http://www.qianzhihe.com.cn/allsort.html";
  19. title = url.split("/")[2];
  20. takeUrlFist(url);
  21. }
  22. // 得到最优节点
  23. public static Element getFather(String url) {
  24. Elements body = readBody(url);
  25. Element bestElement = readChildByMaxNum(body.get(0));
  26. return bestElement;
  27. }
  28. // 测试程序
  29. public static String takeUrlFist(String url) {
  30. bestFather = getFather(url);
  31. // 得到该节点下a
  32. Elements as = bestFather.select("a");
  33. // 得到a 标签的父亲节点
  34. List<Element> aParents = gerFaterPonit(as);
  35. // 得到 a 父节点中tagName数量最多的那些节点
  36. List<Element> aParentsTagNames = takeAparentByTagName(aParents,
  37. bestFather);
  38. // 得到这些节点中className 最多的节点
  39. List<Element> aParentsClassNames = getElementByMaxClassName(aParentsTagNames);
  40. // 在这些节点中找出想要的信息
  41. takeMessage(aParentsClassNames);
  42. return "已经成功提取一个URL";
  43. }
  44. // 得到相同className的 节点的父节点
  45. public static List<Element> gerFaterPonit(Elements elements) {
  46. List<Element> bestElements = new ArrayList<Element>();
  47. for (Element element : elements) {
  48. Element elementFater = element.parent();
  49. bestElements.add(elementFater);
  50. }
  51. return bestElements;
  52. }
  53. //
  54. public static List<Element> getElementByMaxClassName(
  55. List<Element> bestElements) {
  56. String index = takeIndexByClassName(bestElements);
  57. List<Element> bestEList = getElementByClassName(bestElements, index);
  58. return bestEList;
  59. }
  60. // 读取url得到一级节点,该节点含有url
  61. public static Elements readBody(String url) {
  62. Document doc = readUrlFist(url);
  63. Elements body = doc.select("body");
  64. return body;
  65. }
  66. // 得到该节点下的孩子最多的那个节点(这个节点就是含有Url的节点)
  67. public static Element readChildByMaxNum(Element body) {
  68. Elements divOne = body.children();
  69. Element bestElement = divOne.get(0);
  70. int best = divOne.get(0).children().size();
  71. for (int i = 0; i < divOne.size(); i++) {
  72. Elements divTwo = divOne.get(i).select("a");
  73. int temp = divTwo.size();
  74. if (temp > best) {
  75. best = temp;
  76. bestElement = divOne.get(i);
  77. }
  78. }
  79. // System.out.println(bestElement.attr("id"));
  80. return bestElement;
  81. }
  82. // 得到tagName最多的节点
  83. public static List<Element> takeAparentByTagName(List<Element> as,
  84. Element bestElement) {
  85. List<Element> bestElements = new ArrayList<Element>();
  86. Map<String, Integer> aparent = new HashMap<String, Integer>();
  87. String index = "";
  88. for (Element element : as) {
  89. String tag = element.tagName();
  90. if (aparent.containsKey(tag)) {
  91. aparent.put(tag, aparent.get(tag) + 1);
  92. } else {
  93. aparent.put(tag, 1);
  94. }
  95. }
  96. Set<String> keys = aparent.keySet();
  97. Iterator<String> iterable = keys.iterator();
  98. int max = 0;
  99. String best = "";
  100. while (iterable.hasNext()) {
  101. String key = iterable.next();
  102. if (max < aparent.get(key)) {
  103. max = aparent.get(key);
  104. best = key;
  105. }
  106. }
  107. index = best;
  108. bestElements = bestElement.select(index);
  109. return bestElements;
  110. }
  111. // 得到className的名字和他的数量
  112. public static Map<String, Integer> takeMapClass(List<Element> bestElements) {
  113. Map<String, Integer> myClass = new HashMap<String, Integer>();
  114. for (int i = 0; i < bestElements.size(); i++) {
  115. Element element = bestElements.get(i);
  116. String temp = element.className();
  117. int sum = element.children().size();
  118. if (sum == 0) {
  119. sum = 1;
  120. }
  121. if (temp == null || temp.equals("")) {
  122. temp = "iiiuuuzzz";
  123. }
  124. if (myClass.containsKey(temp)) {
  125. myClass.put(temp, myClass.get(temp) + sum);
  126. } else {
  127. myClass.put(temp, sum);
  128. }
  129. }
  130. // System.out.println("myClass.size() "+myClass.size());
  131. return myClass;
  132. }
  133. // 得到className数量最多的节点的索引
  134. public static String takeIndexByClassName(List<Element> bestElements) {
  135. Map<String, Integer> myClass = takeMapClass(bestElements);
  136. Set<String> keys = myClass.keySet();
  137. Iterator<String> iterable = keys.iterator();
  138. int max = 0;
  139. String best = "";
  140. while (iterable.hasNext()) {
  141. String key = iterable.next();
  142. // System.out.println(key+ myClass.get(key));
  143. if (max < myClass.get(key)) {
  144. max = myClass.get(key);
  145. best = key;
  146. }
  147. }
  148. String index = best;
  149. // System.out.println("index :" +index);
  150. return index;
  151. }
  152. // 和className数量次多的节点的索引
  153. public static String takeBetterIndexByClassName(List<Element> bestElements) {
  154. Map<String, Integer> myClass = takeMapClass(bestElements);
  155. String index = takeIndexByClassName(bestElements);
  156. String index2 = "";
  157. Set<String> keys = myClass.keySet();
  158. Iterator<String> iterable = keys.iterator();
  159. int max = 0;
  160. String best = "";
  161. while (iterable.hasNext()) {
  162. String key = iterable.next();
  163. if (!key.equals(index)) {
  164. if (max < myClass.get(key)) {
  165. max = myClass.get(key);
  166. best = key;
  167. }
  168. }
  169. }
  170. index2 = best;
  171. // System.out.println("index2 :" +index2);
  172. return index2;
  173. }
  174. // 根据索引得出所要的节点
  175. public static List<Element> getElementByClassName(
  176. List<Element> bestElements, String index) {
  177. List<Element> elementList = new ArrayList<Element>();
  178. for (Element element : bestElements) {
  179. String temp = element.className();
  180. if (temp == null || temp.equals("")) {
  181. temp = "iiiuuuzzz";
  182. }
  183. if (index.equals(temp)) {
  184. elementList.add(element);
  185. }
  186. }
  187. return elementList;
  188. }
  189. // 得到孩子节点
  190. public static List<Element> takeChildren(List<Element> bestElements) {
  191. List<Element> children = new ArrayList<Element>();
  192. for (Element element : bestElements) {
  193. Elements childrens = element.children();
  194. for (Element element2 : childrens) {
  195. children.add(element2);
  196. }
  197. }
  198. return children;
  199. }
  200. // 得到和自己内容不同的父亲节点
  201. public static Element getParent(Element element) {
  202. Element parent = element.parent();
  203. if (element.siblingElements().size() > 0) {
  204. while (parent.text().equals(element.text())) {
  205. parent = parent.parent();
  206. }
  207. }
  208. return parent;
  209. }
  210. // 得到最优父亲节点
  211. public static void bestParent(List<Element> elements) {
  212. for (int i = 0; i < elements.size(); i++) {
  213. System.out.println(elements.get(i).tagName());
  214. System.out.println(elements.get(i).className());
  215. Element parent = getParent(elements.get(i));
  216. System.out.println(parent.tagName());
  217. System.out.println(parent.className());
  218. //
  219. //
  220. Element parentTwo = getParent(parent);
  221. System.out.println(parentTwo.tagName());
  222. System.out.println(parentTwo.className());
  223. //
  224. Element aparentTwo = parentTwo.parent();
  225. System.out.println(aparentTwo.tagName());
  226. System.out.println(aparentTwo.className());
  227. //
  228. System.out.println(elements.get(i).siblingElements().size());
  229. System.out.println(parent.siblingElements().size());
  230. System.out.println(parentTwo.siblingElements().size());
  231. System.out.println(aparentTwo.siblingElements().size());
  232. // 为什么要选择parent呢?
  233. // 该节点是a 标签的父节点,parent里面可能含有第二级目录
  234. // 如可选择第一级目录呢?这是个难点主要是各大网站的格式不一样
  235. // (jsoup抓到的信息和审查元素看到的结果不一样)
  236. //
  237. // 如果父节点兄弟有两个,可能一个是Title ,一个是want
  238. // 如果是这样的话直接输出二级目录
  239. // 还有一种可能:是这个区域中只有两个want(姑且放一边)
  240. //
  241. // 否则
  242. // 可能的第一种情况是,他的上一个兄弟就是第二级目录,
  243. // (2)他兄弟中的老大是第二级目录,(这种情况不好处理,因为不确定)
  244. //
  245. //
  246. //
  247. // 如何在二级目录上找一级目录呢?
  248. //
  249. //
  250. if (parent.siblingElements().size() == 1) {
  251. if (parentTwo.siblingElements().size() == 1) {
  252. } else {
  253. if (parentTwo.siblingElements().size() + 1 == aparentTwo
  254. .children().size()) {
  255. Element apElementTwo = getParent(aparentTwo);
  256. System.out.println(apElementTwo.className());
  257. if (aparentTwo.siblingElements().size() == 1) {
  258. if (apElementTwo.siblingElements().size() == 1) {
  259. System.out.println("fdsfdsfdsf");
  260. System.out.print(apElementTwo.parent()
  261. .children().first().text());
  262. } else {
  263. System.out.println("ffffffffffffff");
  264. System.out.print(apElementTwo.children()
  265. .first().text());
  266. }
  267. } else {
  268. // System.out.println("dddddddddddddddddddddddd");
  269. if (apElementTwo.siblingElements().size() >= 1) {
  270. // System.out.println("fdsfdsfdsf");
  271. System.out.print(apElementTwo.parent()
  272. .children().first().text());
  273. } else {
  274. // System.out.println("ffffffffffffff");
  275. // System.out.print(apElementTwo.children()
  276. // .first().text());
  277. // System.out.println("dsffffffffff");
  278. }
  279. }
  280. } else {
  281. }
  282. }
  283. System.out.print(" "
  284. + parent.parent().children().first().text());
  285. } else {
  286. // 如果第二级目录在该元素的第一个节点
  287. // 如何找到第一级目录呢?
  288. // 苏宁:
  289. // 如果他的兄弟节点和他父节点的孩子数相同,说明他的父亲和他是亲父子,
  290. // 一级目录就可能是他的第一个兄弟 、
  291. // 判断一个父节点的兄弟,若有一个兄弟,可能是他的title
  292. //
  293. // 也可能是 两个want
  294. //
  295. if (parentTwo.children().size() == parent.siblingElements()
  296. .size() + 1) {
  297. System.out.println("dddddddddddddddddd");
  298. System.out.println(parentTwo.children().first().text());
  299. } else {
  300. if (parentTwo.elementSiblingIndex() - 1 >= 0) {
  301. System.out.print(aparentTwo.children().get(
  302. parentTwo.elementSiblingIndex() - 1).children()
  303. .first().text());
  304. }
  305. }
  306. System.out.print(" "
  307. + parent.children().first().text());
  308. }
  309. // /
  310. System.out.print(" "
  311. + elements.get(i).select("a").text());
  312. System.out.print(" "
  313. + addHttp(addTitle(
  314. elements.get(i).select("a").attr("href"), title)));
  315. System.out.println();
  316. }
  317. }
  318. // 提取需要的信息
  319. public static void takeMessage(List<Element> bestElements) {
  320. threadClass(bestElements);
  321. }
  322. //
  323. public static void threadClass(List<Element> elements) {
  324. for (int i = 0; i < elements.size(); i++) {
  325. Element element = elements.get(i);
  326. Elements elements2 = element.select("a");
  327. for (Element element2 : elements2) {
  328. System.out.print(element2.text());
  329. System.out.println(" "
  330. + addHttp(addTitle(element2.attr("href"), title)));
  331. }
  332. }
  333. }
  334. }

转载于:https://www.cnblogs.com/tomcattd/archive/2013/01/02/2842137.html

发表评论

表情:
评论列表 (有 0 条评论,426人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Jsoup学习总结

    本文摘抄其他博客或者技术论坛,自己搜集整理如下: Jsoup学习总结 摘要 Jsoup是一款比较好的Java版HTML解析器。可直接解析某个URL地址、H

    相关 jsoup总结

    本文摘抄其他博客或者技术论坛,自己搜集整理如下: Jsoup学习总结 摘要 Jsoup是一款比较好的[Java][]版HTML解析器。可直接解析某个U

    相关 Jsoup学习总结

    Jsoup学习总结 摘要 Jsoup是一款比较好的Java版HTML解析器。可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,

    相关 jsoup

    一、Jsoup概述 1.1、简介     jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,