Warum erhalte ich nach einer Weile den 403-Statuscode in Java?
Wenn ich versuche, Statuscodes innerhalb von Websites zu überprüfen, wird nach einer Weile der 403-Antwortcode angezeigt. Zuerst, wenn ich den Code ausführe, senden alle Sites Daten zurück, aber nachdem sich mein Code mit Timer wiederholt hat, sehe ich, dass eine Webseite 403-Antwortcode zurückgibt. Hier ist mein Code.
public class Main {
public static void checkSites() {
Timer ifSee403 = new Timer();
try {
File links = new File("./linkler.txt");
Scanner scan = new Scanner(links);
ArrayList<String> list = new ArrayList<>();
while(scan.hasNext()) {
list.add(scan.nextLine());
}
File linkStatus = new File("LinkStatus.txt");
if(!linkStatus.exists()){
linkStatus.createNewFile();
}else{
System.out.println("File already exists");
}
BufferedWriter writer = new BufferedWriter(new FileWriter(linkStatus));
for(String link : list) {
try {
if(!link.startsWith("http")) {
link = "http://"+link;
}
URL url = new URL(link);
HttpURLConnection.setFollowRedirects(true);
HttpURLConnection http = (HttpURLConnection)url.openConnection();
http.setRequestMethod("HEAD");
http.setConnectTimeout(5000);
http.setReadTimeout(8000);
int statusCode = http.getResponseCode();
if (statusCode == 200) {
ifSee403.wait(5000);
System.out.println("Hello, here we go again");
}
http.disconnect();
System.out.println(link + " " + statusCode);
writer.write(link + " " + statusCode);
writer.newLine();
} catch (Exception e) {
writer.write(link + " " + e.getMessage());
writer.newLine();
System.out.println(link + " " +e.getMessage());
}
}
try {
writer.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println("Finished.");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static void main(String[] args) throws Exception {
Timer myTimer = new Timer();
TimerTask sendingRequest = new TimerTask() {
public void run() {
checkSites();
}
};
myTimer.schedule(sendingRequest,0,150000);
}
}
Wie kann ich das lösen? Vielen Dank
Bearbeiteter Kommentar:
Ich habe http.disconnect () hinzugefügt; zum Schließen der Verbindung nach geprüften Statuscodes.
Auch ich habe hinzugefügt
if(statusCode == 200) { ifSee403.wait(5000); System.out.println("Test message);}}
Aber es hat nicht funktioniert. Der vom Compiler zurückgegebene aktuelle Thread ist kein Eigentümerfehler. Ich muss dies beheben und 200 mit 403 ändern und ifSee403.wait (5000) sagen und den Statuscode erneut versuchen.
Antworten
Eine "Alternative" zu IP / Spoofing / Anonymisierung wäre übrigens, (stattdessen) zu versuchen, dem zu gehorchen, was der Sicherheitscode von Ihnen erwartet. Wenn Sie einen "Scraper" schreiben möchten und wissen, dass es eine "Bot-Erkennung" gibt, bei der Sie Ihren Code nicht debuggen, während Sie die Site immer und immer wieder besuchen , sollten Sie versuchen, den von mir verwendeten HTML-Download zu verwenden Gepostet als Antwort auf die letzte Frage, die Sie gestellt haben.
Wenn Sie den HTML- Code herunterladen und speichern (einmal pro Stunde in einer Datei speichern) und dann Ihren HTML-Parsing- / Überwachungscode mit dem HTML-Inhalt der von Ihnen gespeicherten Datei schreiben , werden Sie sich (wahrscheinlich) an die Sicherheit halten -Anforderungen der Website und weiterhin in der Lage sein, die Verfügbarkeit zu überprüfen .
Wenn Sie JSoup weiterhin verwenden möchten , verfügt diese API über eine Option zum Empfangen von HTML als Zeichenfolge . Wenn Sie also den von mir veröffentlichten HTML-Scrape-Code verwenden und diesen dann HTML Stringauf die Festplatte schreiben, können Sie ihn JSoup so oft zuführen, wie Sie möchten, ohne dass die Sicherheitsüberprüfungen für die Bot-Erkennung ausgelöst werden.
Wenn Sie ab und zu nach ihren Regeln spielen, können Sie Ihren Tester ohne großen Aufwand schreiben.
import java.io.*;
import java.net.*;
...
// This line asks the "url" that you are trying to connect with for
// an instance of HttpURLConnection. These two classes (URL and HttpURLConnection)
// are in the standard JDK Package java.net.*
HttpURLConnection con = (HttpURLConnection) url.openConnection();
// Tells the connection to use "GET" ... and to "pretend" that you are
// using a "Chrome" web-browser. Note, the User-Agent sometimes means
// something to the web-server, and sometimes is fully ignored.
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", "Chrome/61.0.3163.100");
// The classes InputStream, InputStreamReader, and BufferedReader
// are all JDK 1.0 package java.io.* classes.
InputStream is = con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuffer sb = new StringBuffer();
String s;
// This reads each line from the web-server.
while ((s = br.readLine()) != null) sb.append(s + "\n");
// This writes the results from the web-server to a file
// It is using classes java.io.File and java.io.FileWriter
File outF = new File("SavedSite.html");
outF.createNewFile();
FileWriter fw = new FileWriter(outF);
fw.write(sb.toString());
fw.close();
Auch dieser Code ist sehr einfach und verwendet überhaupt keinen speziellen JAR-Bibliothekscode . Die nächste Methode verwendet die JSoup- Bibliothek (die Sie explizit angefordert haben - obwohl ich sie nicht verwende ... Es ist in Ordnung!) ... Dies ist die Methode "parse", die Stringdie gerade gespeicherte analysiert . Sie können dies HTML Stringvon der Festplatte laden und an JSoup senden, indem Sie:
Methodendokumentation: org.jsoup.Jsoup.parse(File in, String charsetName, String baseUri)
Wenn Sie JSoup aufrufen möchten, übergeben Sie eine java.io.FileInstanz wie folgt:
File f = new File("SavedSite.html");
Document d = Jsoup.parse(f, "UTF-8", url.toString());
Ich glaube nicht, dass Sie Timer brauchen ...
WIEDER: Wenn Sie viele Anrufe an den Server tätigen. Der Zweck dieser Antwort ist es, Ihnen zu zeigen, wie Sie die Antwort des Servers auf eine Datei auf der Festplatte speichern, damit Sie nicht viele Anrufe tätigen müssen - NUR EINEN! Wenn Sie Ihre Anrufe an den Server auf einmal pro Stunde beschränken, vermeiden Sie (wahrscheinlich, aber keine Garantie) ein 403 ForbiddenProblem mit der Bot-Erkennung.