如何"扫描"一个网站(或页)有关信息,并把它变成我的计划?
-
26-09-2019 - |
题
好吧,我很多试图找出如何把信息从一个网页,并把它带到我的程序(在Java)。
例如,如果我知道确切的页面我想要的信息,为简单起见,最好买项目的网页,我怎么会获得适当的信息,我需要关闭的那一页?喜欢的题目,价格,说明?
什么这个过程甚至被叫什么?我不知道被甚至开始研究这一点。
编辑:好吧,我在运行测试的JSoup(一个发布的BalusC),但是我继续得到这个错误:
Exception in thread "main" java.lang.NoSuchMethodError: java.util.LinkedList.peekFirst()Ljava/lang/Object;
at org.jsoup.parser.TokenQueue.consumeWord(TokenQueue.java:209)
at org.jsoup.parser.Parser.parseStartTag(Parser.java:117)
at org.jsoup.parser.Parser.parse(Parser.java:76)
at org.jsoup.parser.Parser.parse(Parser.java:51)
at org.jsoup.Jsoup.parse(Jsoup.java:28)
at org.jsoup.Jsoup.parse(Jsoup.java:56)
at test.main(test.java:12)
我有Apache Commons
解决方案
使用HTML分析器喜欢 Jsoup.这有我的偏好上的 其他HTML分析程序提供Java 由于它 支持 jQuery 喜欢 CSS选择.此外,其级代表的一个列表中的节点, Elements
, 中,实现了 Iterable
所以,你可以迭代过它在一个 加强循环 (因此就没有必要的麻烦冗长 Node
和 NodeList
喜欢的类别,在平均Java DOM parser).
这里有一个基本启动的例子(只要把 最新的Jsoup罐子的文件 在类路径):
package com.stackoverflow.q2835505;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class Test {
public static void main(String[] args) throws Exception {
String url = "https://stackoverflow.com/questions/2835505";
Document document = Jsoup.connect(url).get();
String question = document.select("#question .post-text").text();
System.out.println("Question: " + question);
Elements answerers = document.select("#answers .user-details a");
for (Element answerer : answerers) {
System.out.println("Answerer: " + answerer.text());
}
}
}
你可能已经猜到的,这将打印自己的问题和名称的所有answerers.
其他提示
此作为屏幕抓取简称,维基百科有关于本文的更具体的幅刮 。它可以是一个重大的挑战,因为有一些丑陋的,乱七八糟的行动,打破-IF-不换浏览器的HTML聪明在那里,运气这么好。
我会用 JTidy - 这是simlar到JSoup,但我不知道JSoup好。 JTidy把手损坏的HTML并返回一个W3C文档,这样你就可以以此为源,以XSLT来提取你真正感兴趣的内容。如果你不知道XSLT,那么你不妨用JSoup去,作为文档模型比W3C更好工作与
编辑:快速浏览一下在JSoup网站显示,JSoup可能确实是更好的选择。这似乎支持CSS选择器开箱从文档提取的东西。这可能是更容易的工作很多具有比进入XSLT。
你可以使用html分析器(许多有用的链接: java html分析器).
该进程是所谓的'掠夺的网站内容'。搜索'抢网站内容java'为进一步invertigation.
jsoup支持Java 1.5
https://github.com/tburch/jsoup/commit/d8ea84f46e009a7f144ee414a9fa73ea187019a3
看起来像该堆栈是一个错误,并已被固定
JSoup解决方案是伟大的,但如果你需要提取非常简单的只是一些可能更容易使用正则表达式或String.indexOf
正如其他人已经提到的过程被称为刮
你可能想看看HTML,看看你是否能发现是独一无二的,靠近你的文本字符串,那么你可以使用线/炭偏移获取数据。
可能是笨拙在Java中,如果不存在类似的那些任何XML类在System.XML.Linq
发现在C#。
您也可以尝试 jARVEST 。
它是基于一个JRuby的DSL在纯Java引擎蜘蛛刮变换网站。
示例强>:
查找网页内的所有链接(wget
和xpath
是jARVEST的语言的结构):
wget | xpath('//a/@href')
内的Java程序:
Jarvest jarvest = new Jarvest();
String[] results = jarvest.exec(
"wget | xpath('//a/@href')", //robot!
"http://www.google.com" //inputs
);
for (String s : results){
System.out.println(s);
}
我的回答不会可能是对这个问题的作家有用的(我上午8点月中下旬所以不是合适的时机,我猜的),但我认为它可能会为可能遇到这样的回答许多其他开发商是有用的。
今天,我刚刚发布(在我公司的名称)的HTML到POJO完整的框架,您可以使用HTML映射到任何POJO类只是一些注释。库本身也很方便,并设有许多其他的事情都同时是非常可插拔的。你可以看看它在这里: https://github.com/whimtrip/jwht-htmltopojo
使用方法:基本
想象一下,我们需要解析以下HTML页面:
<html>
<head>
<title>A Simple HTML Document</title>
</head>
<body>
<div class="restaurant">
<h1>A la bonne Franquette</h1>
<p>French cuisine restaurant for gourmet of fellow french people</p>
<div class="location">
<p>in <span>London</span></p>
</div>
<p>Restaurant n*18,190. Ranked 113 out of 1,550 restaurants</p>
<div class="meals">
<div class="meal">
<p>Veal Cutlet</p>
<p rating-color="green">4.5/5 stars</p>
<p>Chef Mr. Frenchie</p>
</div>
<div class="meal">
<p>Ratatouille</p>
<p rating-color="orange">3.6/5 stars</p>
<p>Chef Mr. Frenchie and Mme. French-Cuisine</p>
</div>
</div>
</div>
</body>
</html>
让我们来创建我们希望把它映射到POJO的:
public class Restaurant {
@Selector( value = "div.restaurant > h1")
private String name;
@Selector( value = "div.restaurant > p:nth-child(2)")
private String description;
@Selector( value = "div.restaurant > div:nth-child(3) > p > span")
private String location;
@Selector(
value = "div.restaurant > p:nth-child(4)"
format = "^Restaurant n\*([0-9,]+). Ranked ([0-9,]+) out of ([0-9,]+) restaurants$",
indexForRegexPattern = 1,
useDeserializer = true,
deserializer = ReplacerDeserializer.class,
preConvert = true,
postConvert = false
)
// so that the number becomes a valid number as they are shown in this format : 18,190
@ReplaceWith(value = ",", with = "")
private Long id;
@Selector(
value = "div.restaurant > p:nth-child(4)"
format = "^Restaurant n\*([0-9,]+). Ranked ([0-9,]+) out of ([0-9,]+) restaurants$",
// This time, we want the second regex group and not the first one anymore
indexForRegexPattern = 2,
useDeserializer = true,
deserializer = ReplacerDeserializer.class,
preConvert = true,
postConvert = false
)
// so that the number becomes a valid number as they are shown in this format : 18,190
@ReplaceWith(value = ",", with = "")
private Integer rank;
@Selector(value = ".meal")
private List<Meal> meals;
// getters and setters
}
和现在Meal
类,以及:
public class Meal {
@Selector(value = "p:nth-child(1)")
private String name;
@Selector(
value = "p:nth-child(2)",
format = "^([0-9.]+)\/5 stars$",
indexForRegexPattern = 1
)
private Float stars;
@Selector(
value = "p:nth-child(2)",
// rating-color custom attribute can be used as well
attr = "rating-color"
)
private String ratingColor;
@Selector(
value = "p:nth-child(3)"
)
private String chefs;
// getters and setters.
}
我们提供我们的GitHub页面上,上面的代码一些更多的解释。
有关的那一刻,让我们看看如何放弃这一点。
private static final String MY_HTML_FILE = "my-html-file.html";
public static void main(String[] args) {
HtmlToPojoEngine htmlToPojoEngine = HtmlToPojoEngine.create();
HtmlAdapter<Restaurant> adapter = htmlToPojoEngine.adapter(Restaurant.class);
// If they were several restaurants in the same page,
// you would need to create a parent POJO containing
// a list of Restaurants as shown with the meals here
Restaurant restaurant = adapter.fromHtml(getHtmlBody());
// That's it, do some magic now!
}
private static String getHtmlBody() throws IOException {
byte[] encoded = Files.readAllBytes(Paths.get(MY_HTML_FILE));
return new String(encoded, Charset.forName("UTF-8"));
}
另一个短的例子可以发现这里
希望这将有助于有人出来!
查找到卷曲库。我从来没有使用过它在Java中,但我敢肯定,必须有绑定它。基本上,你要做的是发送一个卷曲请求,要“刮”任何网页。该请求将返回一个字符串的源代码的网页。从那里,你将使用正则表达式来分析你的源代码想要的任何数据。这就是通常你将如何做到这一点。