Specific elements from a web using jsoup - web-scraping

I want to get the atomic clock from here http://watches.uhrzeit.org/atomic-clock.php and I wrote this program
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.*;
import java.util.*;
public class da {
/**
* #param args
*/
public static void main(String[] args) {
try{
Document doc=Jsoup.connect("http://watches.uhrzeit.org/atomic-clock.php").get();
Elements spans = doc.select("span[id=anzeige_std]");
System.out.println(spans.text());
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
The problem is why it doesn't print anything(I am noob in this thing and I want to learn).

First, to select an element by its id, use the format element#id. The way you have it is for other attributes.
Second, the clock is on this html:
<div id="timer">
<div id="timeText">
<h2>current time CET</h2>
<div id="anzeige_zeit">22:03:10</div>
<div id="anzeige_datum">Tuesday, 2. August 2016</div>
<div id="anzeige_kw">calendar week 31</div>
</div>
</div>
Which we can target with CSS Selectors like this:
Document doc = Jsoup.connect("http://watches.uhrzeit.org/atomic-clock.php").get();
Element atomicTime = doc.select("div#anzeige_zeit").first();
System.out.println(atomicTime.ownText());
Output
22:08:05

Related

Problem with adding Blocks to Minecraft Mod (1.15.2)

I have spent the last few hours adding a block to my Minecraft Mod. I have looked at several tutorials and none of them work. The blocks are not added to the Creative Inventory and I can't set them by command either. Unfortunately I didn't have any bugs in the console that I could show here. At some point I gave up and tried to do armor, here the same problem. On the other hand: normal items work (You can see the Item "ruby" which woked finde).
Here the code of my main class:
package de.thom.clashOfClasses;
import de.thom.clashOfClasses.init.ArmorMaterialList;
import de.thom.clashOfClasses.init.BlockList;
import de.thom.clashOfClasses.init.ItemList;
import net.minecraft.block.Block;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
#Mod("clashofclasses")
public class ClashOfClasses {
public static ClashOfClasses instance;
public static final String modid = "clashofclasses";
public static final Logger logger = LogManager.getLogger(modid);
public ClashOfClasses() {
instance = this;
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::clientRegistries);
MinecraftForge.EVENT_BUS.register(this);
}
public void setup(final FMLCommonSetupEvent event) {
logger.info("Setup method complete");
}
public void clientRegistries(final FMLClientSetupEvent event) {
logger.info("ClientRegistries method complete");
}
#Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public static class RegistryEvents {
#SubscribeEvent
public static void registerItems(final RegistryEvent.Register<Item> event) {
logger.info("Item Registry started");
event.getRegistry().registerAll(
ItemList.RUBY,
ItemList.ruby_block = new BlockItem(BlockList.ruby_block,new Item.Properties().group(ItemGroup.MISC)).setRegistryName(BlockList.ruby_block.getRegistryName())
);
logger.info("Items registerd");
}
#SubscribeEvent
public static void registerBlocks(final RegistryEvent.Register<Block> event) {
logger.info("Block Registry started");
event.getRegistry().registerAll
(
BlockList.ruby_block = new Block(Block.Properties.create(Material.IRON).hardnessAndResistance(2.0f,3.0f).lightValue(5).sound(SoundType.METAL)).setRegistryName(location("ruby_block"))
);
logger.info("Blocks registerd");
}
private static ResourceLocation location(String name){
return new ResourceLocation(ClashOfClasses.modid, name);
}
}
}
Here is the code of BlockList
package de.thom.clashOfClasses.init;
import net.minecraft.block.Block;
public class BlockList {
public static Block ruby_block;
}
Here is the code of ItemList:
package de.thom.clashOfClasses.init;
import de.thom.clashOfClasses.ClashOfClasses;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.util.ResourceLocation;
public class ItemList
{
//Test Items
public static Item RUBY = new Item(new Item.Properties().group(ItemGroup.MATERIALS)).setRegistryName(location("ruby"));
public static Item ruby_block;
private static ResourceLocation location(String name){
return new ResourceLocation(ClashOfClasses.modid, name);
}
}
A block in the world and a “block” in an inventory are very different things. A block in the world is represented by an IBlockState, and its behavior defined by an instance of Block. Meanwhile, an item in an inventory is an ItemStack, controlled by an Item. As a bridge between the different worlds of Block and Item, there exists the class ItemBlock. ItemBlock is a subclass of Item that has a field block that holds a reference to the Block it represents. ItemBlock defines some of the behavior of a “block” as an item, like how a right click places the block. It’s possible to have a Block without an ItemBlock. (E.g. minecraft:water exists a block, but not an item. It is therefore impossible to hold it in an inventory as one.)
When a block is registered, only a block is registered. The block does not automatically have an ItemBlock. To create a basic ItemBlock for a block, one should use new ItemBlock(block).setRegistryName(block.getRegistryName()). The unlocalized name is the same as the block’s. Custom subclasses of ItemBlock may be used as well. Once an ItemBlock has been registered for a block, Item.getItemFromBlock can be used to retrieve it. Item.getItemFromBlock will return null if there is no ItemBlock for the Block, so if you are not certain that there is an ItemBlock for the Block you are using, check for null.
from https://mcforge.readthedocs.io/en/latest/blocks/blocks/.
I short, if everything works, your blocks shoudnt appear in your
#ObjectHolder(modid)
#Mod.EventBusSunscriber(modid = modid, bus = Bus.Mod)
public class BlockInit {
public static final Block example_block = null;
#SubscribeEvent
public static void registerBlocks(final RegistryEvent.Register<Block> event) {
event.getRegistry().register(new Block(Block.Properties.create(Material)).setRegistry("example_block"));
}
#SubscribeEvent
public static void registerBlockItems(final RegistryEvent.Register<Item> event){
event.getRegistry().register(new BlockItem(example_item, new Item.Properties().group(ItemGroup)).setRegistry("example_block"));
}
That works for me just replace example_block with the name of your block and add more properties if you want
for another block just repeat the event.getRegistry stuff and use the name of your new block instead of example_block.
and don't forget to do the json files

Jsoup to parse multiple websites for links published today

I am currently using jsoup (below) to output a .csv of links which include a string date format in the url from just one website.
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.io.FileOutputStream;
import java.io.PrintStream;
import org.jsoup.nodes.Element;
public class readAllLinks {
public static Set<String> uniqueURL = new HashSet<String>();
public static String my_site;
public static String published = ("20180731");
public static void main(String[] args) {
readAllLinks obj = new readAllLinks();
my_site = ("news24.com/SouthAfrica/News");
obj.get_links("https://www.news24.com/SouthAfrica/News/");
}
private void get_links(String url) {
try {
Document doc = Jsoup.connect(url).get();
Elements links = doc.select("a");
FileOutputStream fout=new FileOutputStream("links.csv");
PrintStream csv=new PrintStream(fout);
links.stream().map((link) -> link.attr("abs:href")).forEachOrdered((this_url) -> {
boolean add = uniqueURL.add(this_url);
if (add && this_url.contains(my_site) && this_url.contains(published)) {
System.out.println(this_url);
get_links(this_url);
}
if (this_url.contains(published))
csv.println(this_url);
} );
} catch (IOException ex) {
}
}
}
Instead I would like to make a csv of links published today (i.e using today's date) from multiple websites.
How do you specify the .select for the newly published links to get the date contained in a span?
And how do you parse multiple websites from a list?
Many thanks for your help.
This will select all links that contains value of variable 'published'.
Elements links = doc.select("a[href*="+published+"]");

What's a good observable appendable base for a TextArea?

I have a StringBuffer that is occasionally appended with new information.
In a separate module, I have a JavaFX TextArea that displays that StringBuffer.
Right now, I have to manually update the TextArea every time the underlying data is modified.
Is there something like an ObservableList (which I use for TableViews) that I can use as the back-end data for the TextArea instead, so I don't have to manually manage pushing the changes to the display?
I am not attached to using a StringBuffer. I'm glad to use any appendable data structure to hold text.
You can consider something simple like this:
import javafx.beans.binding.StringBinding;
public class ObservableStringBuffer extends StringBinding {
private final StringBuffer buffer = new StringBuffer() ;
#Override
protected String computeValue() {
return buffer.toString();
}
public void set(String content) {
buffer.replace(0, buffer.length(), content);
invalidate();
}
public void append(String text) {
buffer.append(text);
invalidate();
}
// wrap other StringBuffer methods as needed...
}
This enables easy coding for binding to a text area. You can simply do
TextArea textArea = new TextArea();
ObservableStringBuffer buffer = new ObservableStringBuffer();
textArea.textProperty().bind(buffer);
// ...
buffer.append("Hello world");
However, it's important to note here that you don't transfer the efficiency of the buffer API to the text area: the text area simply has a textProperty() representing its text, which can still only really be modified by set(...) and setValue(...). In other words, when you append to the buffer, you essentially end up with textArea.setText(textArea.getText() + "Hello world") (not textArea.appendText("Hello world"). If you're just looking for a clean API, then this should work for you; if you're looking for something efficient, you would have to "wire" the calls to appendText yourself, since that is simply not supported by the text area's textProperty().
Here's a SSCCE using the above class:
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;
public class ObservableStringBufferTest extends Application {
private int counter ;
#Override
public void start(Stage primaryStage) {
ObservableStringBuffer buffer = new ObservableStringBuffer();
TextArea textArea = new TextArea();
textArea.setEditable(false);
textArea.textProperty().bind(buffer);
buffer.set("Item 0");
Timeline timeline = new Timeline(new KeyFrame(
Duration.seconds(1),
e -> buffer.append("\nItem "+(++counter))));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
primaryStage.setScene(new Scene(new StackPane(textArea)));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Dropdown option menu repeat same option

This is what I implemented using spring-mvc. As I observed resultSet in ChildNameAccess.java works properly. As I put print statement here it print what I really need as the options. But dropdown box repeats the one result in the resultset object. Could anybody trace this and tell me what's wrong with my jsp please?
controller.java
#RequestMapping(value="/my_children", method = RequestMethod.GET)
public void viewMyChild(Model model) {
ChildNameAccess childNameDAO = new ChildNameAccess();
try{
java.util.List<Child> children = childNameDAO.getChildDataByMotherId("M-2");
model.addAttribute("children",children);
System.out.println(children);
}
catch (SQLException e) {
e.printStackTrace();
}
}
my_children.jsp
<div class="container-fluid bg-2 text-center">
<form:form method="get" >
<div class="div_box">
<select>
<option value="top" >Select child</option>
<c:forEach items="${children}" var="children">
<option value="" >${children.firstName} ${children.lastName}</option>
</c:forEach>
</select>
<br>
<div align ="justify">
<button type="button" onclick="location.href='/web/mother/my_child_details'" class="btn btn-success active">View Details</button>
</div>
</div>
</form:form>
ChildNameAccess.java
package com.emidwife.web.models.dataAccess;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.ArrayList;
import com.emidwife.web.models.entities.Child;
import com.emidwife.web.models.utilities.Database;
public class ChildNameAccess {
private Database connection = new Database();
Child child = new Child();
public List<Child> getChildDataByMotherId(String motherID) throws SQLException {
connection.openConnection();
List<Child> children = new ArrayList<Child>();
try{
ResultSet resultSet = connection.getData("SELECT * FROM childdetails WHERE MotherID=\'" + motherID + "\'");
while(resultSet.next()){
System.out.println(resultSet.getString("FirstName"));
child.setChildId(resultSet.getString("ChildID"));//database column -->ChildID
child.setMotherId(resultSet.getString("MotherID"));
child.setFirstName(resultSet.getString("FirstName"));
child.setLastName(resultSet.getString("LastName"));
System.out.println(children);
children.add(child);
System.out.println(children);
}
}
catch (SQLException e) {
e.printStackTrace();
}
finally{
connection.closeConnection();
}
return children;
}
}
In your ChildNameAccess.java child is defined outside resultSet iteration, try creating new Child object inside the loop every time it loops. Because in Java strings are immutable, and you actually cannot change the value of a string. Means when you do child.setFirstName(resultSet.getString("FirstName"));
like wise original value of the firstName String is still in the memory and the other variables which are pointed to it haven't changed.
while(resultSet.next()){
Child child = new Child();
child.setChildId(resultSet.getString("ChildID"));//database column -->ChildID
child.setMotherId(resultSet.getString("MotherID"));
child.setFirstName(resultSet.getString("FirstName"));
System.out.println(resultSet.getString("FirstName"));
child.setLastName(resultSet.getString("LastName"));
children.add(child);
}
You need to create child object for each resultset row. You are not creating it. I have fixed it as follows.
package com.emidwife.web.models.dataAccess;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.ArrayList;
import com.emidwife.web.models.entities.Child;
import com.emidwife.web.models.utilities.Database;
public class ChildNameAccess {
private Database connection = new Database();
Child child = null;
public List<Child> getChildDataByMotherId(String motherID) throws SQLException {
connection.openConnection();
List<Child> children = new ArrayList<Child>();
try{
ResultSet resultSet = connection.getData("SELECT * FROM childdetails WHERE MotherID=\'" + motherID + "\'");
while(resultSet.next()){
child = new Child();
System.out.println(resultSet.getString("FirstName"));
child.setChildId(resultSet.getString("ChildID"));//database column -->ChildID
child.setMotherId(resultSet.getString("MotherID"));
child.setFirstName(resultSet.getString("FirstName"));
child.setLastName(resultSet.getString("LastName"));
System.out.println(children);
children.add(child);
System.out.println(children);
}
}
catch (SQLException e) {
e.printStackTrace();
}
finally{
connection.closeConnection();
}
return children;
}}

Mediaplayer in JAR

This code compile in Intellij, but it does not work in jar.
Working with getResourceAsStream() or getResource doest not solve the problem.
(I have tried out with Image like Image image = newImage(getClass().getResourceAsStream("image.png");and it does work)
package Sound;
import javafx.application.Application;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.io.File;
/**
*/
public class TestSound extends Application{
public TestSound() {
play();
}
#Override
public void start(Stage primaryStage) throws Exception {
new TestSound().play();
}
private void play(){
String mainsound = "src/res/sound/main.mp3";
Media i = null;
i = new Media( new File(mainsound).toURI().toString());
MediaPlayer mediaPlayer = new MediaPlayer(i);
mediaPlayer.play();
mediaPlayer.setStopTime(new Duration(120000));
mediaPlayer.setCycleCount(MediaPlayer.INDEFINITE);
}
public static void main (String[] args){
launch(args);
}
}
EDIT:
Media i = new Media(getClass().getClassLoader().getResource(mainsound));
wont work, because the constructor need a String.
but also
Media i = new Media(getClass().getClassLoader().getResource(mainsound).toString());
new MediaPlayer(i).play();
does not work.
ofcourse mainsound="res/sound/main.mp3";
After extraction of jar with winrar
I got dictionary of sound with include the
testsound.class and main.mp3
And another dictionary of res with include main.mp3
Both dictionary are in the same root.
getClass().getResource("res/sound/main.mp3") is going to look for a resource named res/sound/main.mp3 relative to the current class. Since your class is in the sound package, it's effectively going to look for /sound/res/sound/main.mp3, which is not where the resource is located in your jar.
If the list of entries in the jar file is showing
/sound/main.mp3
then the following should work:
String mediaURL = getClass().getResource("/sound/main.mp3").toExternalForm();
// for debugging:
System.out.println(mediaURL);
Media i = new Media(mediaURL);
Instead of using getClass ().getResource (...) it would be ideal to use it like
Media m = new Media ("/myMedia.mp3");//if the media exists in default package
or
Media m = new Media ("/mypackage/myMedia.mp3");//if the media exists in mypackage

Resources