Extract text from html file using java - java

I am working on a text crawler and I need to extract a certain text from several sites. I have used jsoup html parser:
Document doc = Jsoup.connect("http://www.aljazeera.net/programs/behindthenews/2014/11/9/%D8%A3%D8%B3%D8%A8%D8%A7%D8%A8-%D9%88%D8%AF%D9%84%D8%A7%D9%84%D8%A7%D8%AA-%D8%A7%D8%B3%D8%AA%D9%85%D8%B1%D8%A7%D8%B1-%D8%A7%D9%84%D8%B5%D8%AF%D8%A7%D9%85-%D8%A8%D8%AC%D8%A7%D9%85%D8%B9%D8%A7%D8%AA-%D9%85%D8%B5%D8%B1").get();
Elements ps = doc.select("p");
String s = Jsoup.parse(ps.text()).text();
PrintWriter out = new PrintWriter("newFile.txt", "UTF-8");
out.write(s);
out.close();
This algorithm gets me an unwanted text, the wanted text is under this tag <p dir="rtl">
And when I change my selection to Elements ps = doc.select("p dir=rtl");, it returns a compilation error.
Is there any way to make it just select this wanted tag?

the wanted text is under this tag <p dir="rtl">
You need to use the following CSS query:
p /* Select any p element... */
[dir=rtl] /* ... with a 'dir' attribute set to "rtl" */
#NavidShakibapour http://www.aljazeera.net/programs/behindthenews/2014/11/9/أسباب-ودلالات-استمرار-الصدام-بجامعات-مصر
The above url need to be encoded. We'll use the URI#create helper method. On the returned URI instance, we'll invoke the toASCIIString method.
URI uri = URI //
.create("http://www.aljazeera.net/programs/behindthenews/2014/11/9/أسباب-ودلالات-استمرار-الصدام-بجامعات-مصر") //
.toASCIIString();
Here is a working sample code:
SAMPLE CODE
Document doc = Jsoup.connect("http://www.aljazeera.net/").get();
Elements sublinks = doc.select("a[href*=/programs/behindthenews]");
System.out.println("Sublinks found: " + sublinks.size() + "\n*****");
for (Element sublink : sublinks) {
String url = URI.create(sublink.absUrl("href")).toASCIIString();
Document subLinkPage = Jsoup.connect(url).get();
System.out.println(subLinkPage.select("p[dir=rtl]"));
System.out.println("-------------------------");
}
OUTPUT (content stripped)
Sublinks found: 5
*****
<p dir="rtl">وحول هذا الموضوع وصف مدير مكتب الجزيرة في موسكو زاور شوج قرار الرئيس بوتين بالخطوة المفاجئة، باعتبار أن الروس وضعوا سقفا زمنيا مفتوحا لتدخلهم العسكري، يتراوح بين 12 و18 شهرا.</p>
<p dir="rtl">
(...)
-------------------------
<p dir="rtl">وحول هذا الموضوع وصف مدير مكتب الجزيرة في موسكو زاور شوج قرار الرئيس بوتين بالخطوة المفاجئة، باعتبار أن الروس وضعوا سقفا زمنيا مفتوحا لتدخلهم العسكري، يتراوح بين 12 و18 شهرا.</p>
<p dir="rtl">
(...)
-------------------------
(...)

The below code will capture all the <p dir="rtl"> tags:
String uri = URI.create("example.com").toASCIIString();
Document doc = Jsoup.connect(uri).get();
Elements pElements = doc.select("p[dir=rtl]");
StringBuilder sb = new StringBuilder();
for (Element element : pElements) {
sb.append(element.text());
}
PrintWriter out = new PrintWriter("newFile.txt", "UTF-8");
out.write(sb.toString());
out.close();
The only tricky thing is that, you need to use encoded URLs (and not the one with Arabic letters).
Edit 1:
URL encoding can be done in the code.

Related

jsoup: parse data of certain tag which is just after a particular tag

I am trying to parse certain information through jsoup in Java from last 3 days -_-, this is my code:
Document document = Jsoup.connect(urlofpage).get();
Elements links = document.select(".contentBox");
for (Element link : links) {
// String name = link.text();
String title = link.select("h2").text();
String content = link.select("p").text();
System.out.println(title);
System.out.println(content);
}
It is fetching the data as it is directed, fetching the data of h2 and p separated, but the problem is, I want to parse the data inside of <p> tag which is just after every <h2> tag.
For example (HTML content):
<h2>main content</h2>
<div class="acx"><div>
<p>content</p>
<p>content 2</p>
<h2>content 2</h2>
<div class="acx"><div>
<p>new content od 2</p>
<p>new 2</p>
Now it should fetch like (in array):
array[0] = "content content 2",
array[1] = "new content od 2 new 2",
Any solutions?
You can play with "~" next element selector. For example
link.select("h2 ~ p").get(0).text(); // returns "content"
link.select("h2 ~ p").get(1).text(); // returns "new content od 2"
Just use your initial approach to iterate all necessary tags within selected .contentBox class:
Document document = Jsoup.connect(urlofpage).get();
Elements links = document.select(".contentBox");
for (Element link : links) {
for (Element h2Tag : link.select("h2"))
{
System.out.println(h2Tag.text());
}
for (Element pTag : link.select("p"))
{
System.out.println(pTag.text());
}
}

How to access the subclass using jsoup

I want to access this webpage: https://www.google.com/trends/explore#q=ice%20cream and extract the data within in the center line graph. The html file is(Here, I only paste the part that I use.):
<div class="center-col">
<div class="comparison-summary-title-line">...</div>
...
<div id="reportContent" class="report-content">
<!-- This tag handles the report titles component -->
...
<div id="report">
<div id="reportMain">
<div class="timeSection">
<div class = "primaryBand timeBand">...</div>
...
<div aria-lable = "one-chart" style = "position: absolute; ...">
<svg ....>
...
<script type="text/javascript">
var chartData = {...}
And the data I used is stored in the script part(last line). My idea is to get the class "report-content" first, and then select script. And my code follows as:
String html = "https://www.google.com/trends/explore#q=ice%20cream";
Document doc = Jsoup.connect(html).get();
Elements center = doc.getElementsByClass("center-col");
Element report = doc.getElementsByClass("report-content");
System.out.println(center);
System.out.println(report);
When I print "center" class, I can get all the subclasses content except the "report-content", and when I print the "report-content", the result is only like:
<div id="reportContent" Class="report-content"></div>
And I also try this:
Element report = doc.select(div.report-content).first();
but still does not work at all. How could I get the data in the script here? I appreciate your help!!!
Try this url instead:
https://www.google.com/trends/trendsReport?hl=en&q=${keywords}&tz=${timezone}&content=1
where
${keywords} is an encoded space separated keywords list
${timezone} is an encoded timezone in the Etc/GMT* form
DEMO
SAMPLE CODE
String myKeywords = "ice cream";
String myTimezone = "Etc/GMT+2";
String url = "https://www.google.com/trends/trendsReport?hl=en&q=" + URLEncoder.encode(keywords, "UTF-8") +"&tz="+URLEncoder.encode(myTimezone, "UTF-8")+"&content=1";
Document doc = Jsoup.connect(url).timeout(10000).get();
Element scriptElement = doc.select("div#TIMESERIES_GRAPH_0-time-chart + script").first();
if (scriptElement==null) {
throw new RuntimeException("Unable to locate trends data.");
}
String jsCode = scriptElement.html();
// parse jsCode to extract charData...
References:
How to extract the text of a <script> element with Jsoup?
Trying getting the same by Id, you would get the complete tag

Parsing elements within div using Jsoup

Here is the html I'm trying to parse:
<div class="entry">
<img src="http://www.example.com/image.jpg" alt="Image Title">
<p>Here is some text</p>
<p>Here is some more text</p>
</div>
I want to get the text within the <p>'s into one ArrayList. I've tried using Jsoup for this.
Document doc = Jsoup.parse(line);
Elements descs = doc.getElementsByClass("entry");
for (Element desc : descs) {
String text = desc.getElementsByTag("p").first().text();
myArrayList.add(text);
}
But this doesn't work at all. I'm quite new to Jsoup but it seems it has its limitations. If I can get the text within <p> into one ArrayList using Jsoup, how can I accomplish that? If I must use some other means to parse the html, let me know.
I'm using a BufferedReader to read the html file one line at a time.
You could change your approach to the following:
Document doc = Jsoup.parse(line);
Elements pElems = doc.select("div.entry > p");
for (Element pElem : pElems) {
myArrayList.add(pElem.data());
}
Not sure why you are reading the html line by line. However if you want to read the whole html use the code below:
String line = "<div class=\"entry\">" +
"<img src=\"http://www.example.com/image.jpg\" alt=\"Image Title\">" +
"<p>Here is some text</p>" +
"<p>Here is some more text</p>" +
"</div>";
Document doc = Jsoup.parse(line);
Elements descs = doc.getElementsByClass("entry");
List<String> myArrayList = new ArrayList<String>();
for (Element desc : descs) {
Elements paragraphs = desc.getElementsByTag("p");
for (Element paragraph : paragraphs) {
myArrayList.add(paragraph.text());
}
}
In your for-loop:
Elements ps = desc.select("p");
(http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#select(java.lang.String))
Try this:
Document doc = Jsoup.parse(line);
String text = doc.select("p").first().text();

How to get text & Other tags between specific tags using Jericho HTML parser?

I have a HTML file which contains a specific tag, e.g. <TABLE cellspacing=0> and the end tag is </TABLE>. Now I want to get everything between those tags. I am using Jericho HTML parser in Java to parse the HTML. Is it possible to get the text & other tags between specific tags in Jericho parser?
For example:
<TABLE cellspacing=0>
<tr><td>HELLO</td>
<td>How are you</td></tr>
</TABLE>
Answer:
<tr><td>HELLO</td>
<td>How are you</td></tr>
Once you have found the Element of your table, all you have to do is call getContent().toString(). Here's a quick example using your sample HTML:
Source source = new Source("<TABLE cellspacing=0>\n" +
" <tr><td>HELLO</td> \n" +
" <td>How are you</td></tr>\n" +
"</TABLE>");
Element table = source.getFirstElement();
String tableContent = table.getContent().toString();
System.out.println(tableContent);
Output:
<tr><td>HELLO</td>
<td>How are you</td></tr>
Aby, I walk down the code for all elements and show on screen. Maybe help you.
List<Element> elementListTd = source.getAllElements(HTMLElementName.TD);
//Scroll through the list of elements "td" page
for (Element element : elementListTd) {
if (element.getAttributes() != null) {
String td = element.getAllElements().toString();
String tag = "td";
System.out.println("TD: " + td);
System.out.println(element.getContent());
String conteudoAtributo = element.getTextExtractor().toString();
System.out.println(conteudoAtributo);
if (td.contains(palavraCompara)) {
tabela.add(conteudoAtributo);
}
}

jsoup tag extraction problem

test: example test1:example1
Elements size = doc.select("div:contains(test:)");
how can i extract the value example and example1 from this html tag....using jsoup..
Since this HTML is not semantic enough for the final purpose you have (a <br> cannot have children and : is not HTML), you can't do much with a HTML parser like Jsoup. A HTML parser isn't intented to do the job of specific text extraction/tokenizing.
Best what you can do is to get the HTML content of the <div> using Jsoup and then extract that further using the usual java.lang.String or maybe java.util.Scanner methods.
Here's a kickoff example:
String html = "<div style=\"height:240px;\"><br>test: example<br>test1:example1</div>";
Document document = Jsoup.parse(html);
Element div = document.select("div[style=height:240px;]").first();
String[] parts = div.html().split("<br />"); // Jsoup transforms <br> to <br />.
for (String part : parts) {
int colon = part.indexOf(':');
if (colon > -1) {
System.out.println(part.substring(colon + 1).trim());
}
}
This results in
example
example1
If I was the HTML author, I would have used a definition list for this. E.g.
<dl id="mydl">
<dt>test:</dt><dd>example</dd>
<dt>test1:</dt><dd>example1</dd>
</dl>
This is more semantic and thus more easy parseable:
String html = "<dl id=\"mydl\"><dt>test:</dt><dd>example</dd><dt>test1:</dt><dd>example1</dd></dl>";
Document document = Jsoup.parse(html);
Elements dts = document.select("#mydl dd");
for (Element dt : dts) {
System.out.println(dt.text());
}

Categories