Optimizando el analizador HTML de Java -- java campo con performance campo con html campo con parsing campo con web-scraping camp codereview Relacionados El problema

Optimizing Java HTML parser


2
vote

problema

Español

Escribí un programa que pasa por una página web y devuelve las coincidencias de RIGEX. Lo usé en mi cuenta de LetterboxD.com para pasar por todas mis películas (más de 900 entradas) y luego encontrar el campo Géneros para cada uno de ellos para obtener la cantidad de películas que he visto en cada género (que hace 53 páginas Para obtener URL para las películas y 945 páginas de películas para obtener géneros). Pero tomó más de 30 minutos (el resultado fue correcto). Una página web normal lleva aproximadamente un segundo. Así que me encantaría obtener algunas sugerencias para optimizarlo.

  import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern;  import javax.net.ssl.HttpsURLConnection;  /**  * This program extracts information from html pages.  * @author Martin Lukáš  *  */ public final class HtmlExtractor {      private final String site;     private final Pattern p;     private Matcher matcher;     private List<String> listOfMatches;     private String inlineRegex;     private boolean completed = false;      /**      * This constructor creates an object that finds at most one match per line.      * @param site - your target      * @param regex - regular expression for finding matches      */     public HtmlExtractor(String site, String regex) {         this.site = site;         p = Pattern.compile(regex);         listOfMatches = new ArrayList<>();     }      /**      * This constructor creates an object       * that finds the same, as well as multiple matches per line.      * @param site - your target      * @param regex - regular expression for finding matches      * @param inlineRegex - regular expression for dividing a line      */     public HtmlExtractor(String site, String regex, String inlineRegex) {         this.site = site;         p = Pattern.compile(regex);         listOfMatches = new ArrayList<>();         this.inlineRegex = inlineRegex;     }      public String getSite() {return site;}     public String getRegex() {return p.pattern();}     public String getInlineRegex() {return inlineRegex;}      public List<String> getMatches() {         if (completed) return listOfMatches;         else {             System.out.println("The extraction didn't take place.");             return null;         }     }      public boolean isComplete() {return completed;};      public void findMatches() {         try {             extractFrom(new URL(site));         } catch (MalformedURLException e) {             System.out.println("The url couldn't be resolved.");         }         completed = true;     }      private void checkLine(String l) {         matcher = p.matcher(l);         if (matcher.find()) {             if (inlineRegex != null) {                 for (String s: l.split(inlineRegex)) {                     matcher = p.matcher(s);                     if (matcher.find()) addToList();                 }             }         }     }      private void addToList() {         listOfMatches.add(matcher.group(1));     }      private void extractFrom(URL u) {         String line = "";         if (site.startsWith("https")) {             try (BufferedReader in = new BufferedReader(                     new InputStreamReader(                             ((HttpsURLConnection) u.openConnection()).getInputStream(),                              "UTF-8"))) {                 while ((line = in.readLine()) != null) {                     checkLine(line);                 }             } catch (IOException e) {                 System.out.println("This url doesn't exist.");             }         } else {             try (BufferedReader in = new BufferedReader(                     new InputStreamReader(u.openStream()))) {                 while ((line = in.readLine()) != null) {                     checkLine(line);                 }             } catch (IOException e) {                 System.out.println("Couldn't connect to the url.");             }         }     } }   public class Main {      public static void main(String[] args) {         HtmlExtractor h = new HtmlExtractor(                 "http://letterboxd.com//film/double-indemnity/",                  "(?:films/genre/)(.*)(?=/" class)",                 "box-link"         );         h.findMatches();         for (String s : h.getMatches()) System.out.println(s);     } }   

El método principal () pasa por la página para doble indemnidad y devuelve los géneros. Toma alrededor de 1.5 s.

Mi conexión a Internet no debe ser un problema (10 Mbps).

Original en ingles

I wrote a program that goes through a webpage and returns matches of regex. I used it on my letterboxd.com account to go through all of my movies (over 900 entries) and then find genres field for each of them in order to get the number of movies I've seen in each genre (that makes 53 pages for getting urls for the movies and 945 movie pages for getting genres). But it took over 30 minutes (the result was correct). A normal webpage takes about a second. So I'd love to get some suggestions for optimizing it.

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern;  import javax.net.ssl.HttpsURLConnection;  /**  * This program extracts information from html pages.  * @author Martin Lukxc3xa1xc5xa1  *  */ public final class HtmlExtractor {      private final String site;     private final Pattern p;     private Matcher matcher;     private List<String> listOfMatches;     private String inlineRegex;     private boolean completed = false;      /**      * This constructor creates an object that finds at most one match per line.      * @param site - your target      * @param regex - regular expression for finding matches      */     public HtmlExtractor(String site, String regex) {         this.site = site;         p = Pattern.compile(regex);         listOfMatches = new ArrayList<>();     }      /**      * This constructor creates an object       * that finds the same, as well as multiple matches per line.      * @param site - your target      * @param regex - regular expression for finding matches      * @param inlineRegex - regular expression for dividing a line      */     public HtmlExtractor(String site, String regex, String inlineRegex) {         this.site = site;         p = Pattern.compile(regex);         listOfMatches = new ArrayList<>();         this.inlineRegex = inlineRegex;     }      public String getSite() {return site;}     public String getRegex() {return p.pattern();}     public String getInlineRegex() {return inlineRegex;}      public List<String> getMatches() {         if (completed) return listOfMatches;         else {             System.out.println("The extraction didn't take place.");             return null;         }     }      public boolean isComplete() {return completed;};      public void findMatches() {         try {             extractFrom(new URL(site));         } catch (MalformedURLException e) {             System.out.println("The url couldn't be resolved.");         }         completed = true;     }      private void checkLine(String l) {         matcher = p.matcher(l);         if (matcher.find()) {             if (inlineRegex != null) {                 for (String s: l.split(inlineRegex)) {                     matcher = p.matcher(s);                     if (matcher.find()) addToList();                 }             }         }     }      private void addToList() {         listOfMatches.add(matcher.group(1));     }      private void extractFrom(URL u) {         String line = "";         if (site.startsWith("https")) {             try (BufferedReader in = new BufferedReader(                     new InputStreamReader(                             ((HttpsURLConnection) u.openConnection()).getInputStream(),                              "UTF-8"))) {                 while ((line = in.readLine()) != null) {                     checkLine(line);                 }             } catch (IOException e) {                 System.out.println("This url doesn't exist.");             }         } else {             try (BufferedReader in = new BufferedReader(                     new InputStreamReader(u.openStream()))) {                 while ((line = in.readLine()) != null) {                     checkLine(line);                 }             } catch (IOException e) {                 System.out.println("Couldn't connect to the url.");             }         }     } }   public class Main {      public static void main(String[] args) {         HtmlExtractor h = new HtmlExtractor(                 "http://letterboxd.com//film/double-indemnity/",                  "(?:films/genre/)(.*)(?=/\" class)",                 "box-link"         );         h.findMatches();         for (String s : h.getMatches()) System.out.println(s);     } } 

The main() method goes through the page for Double Indemnity and returns the genres. Takes about 1.5 s.

My internet connection shouldn't be a problem (10 Mbps).

              
   
   

Lista de respuestas

1
 
vote
  int1  

Debe formatear su código correctamente. Esto es difícil de leer para mí.

Aquí está el formato recomendado:

  int2  

Ya no estamos en los años 80; Tienes un espacio de pantalla mucho.


  int3  

Puede combinar estos dos indicaciones anidadas si las declaraciones:

  int4  
 
public String getSite() {return site;} public String getRegex() {return p.pattern();} public String getInlineRegex() {return inlineRegex;}  public List<String> getMatches() {     if (completed) return listOfMatches;     else {         System.out.println("The extraction didn't take place.");         return null;     } }  public boolean isComplete() {return completed;}; 

You ought to format your code properly. This is hard to read for me.

Here's the recommended formatting:

public String getSite() {     return site; }  public String getRegex() {     return p.pattern(); }  public String getInlineRegex() {     return inlineRegex; }  public List<String> getMatches() {     if (completed) {         return listOfMatches;     } else {         System.out.println("The extraction didn't take place.");         return null;     } }  public boolean isComplete() {     return completed; } 

We're not in the 80's anymore; you have screen space plenty.


    if (matcher.find()) {         if (inlineRegex != null) {             for (String s: l.split(inlineRegex)) {                 matcher = p.matcher(s);                 if (matcher.find()) addToList();             }         }     } 

You can combine these two nested if statements:

    if (matcher.find() && inlineRegex != null) {         for (String s: l.split(inlineRegex)) {             matcher = p.matcher(s);             if (matcher.find()) {                 addToList();             }         }     } 
 
 

Relacionados problema

11  ¿Es esta la forma en ello a Web-Scrape a una imagen de portada de libros?  ( Is this the clojure way to web scrape a book cover image ) 
¿Hay una manera de escribir esto mejor o más de manera de engaño? Especialmente la última parte con with-open y el let . ¿Debo poner el formulario 9988776...

6  BFS / DFS Web Crawler  ( Bfs dfs web crawler ) 
He construido un rastreador web que comienza en una URL de origen y rastrea la web con un método BFS o DFS. Todo está funcionando bien, pero la actuación es h...

4  Raspando html usando sopa hermosa  ( Scraping html using beautiful soup ) 
He escrito un script usando una hermosa sopa para raspar un poco de html y hacer algunas cosas y producir HTML de vuelta. Sin embargo, no estoy convencido con...

6  TRIVAGO Hotels Precio Checker  ( Trivago hotels price checker ) 
He decidido escribir mi primer proyecto en Python. Me gustaría escuchar alguna opinión de usted. Descripción del script: Generar URLS TrivAGO para hote...

5  Cómo obtener información de los países de un sitio web que no está utilizando una verbanización consistente  ( Getting information of countries out of a website that isnt using consistent ve ) 
de este sitio web Necesitaba agarrar la información para cada país e insértelo en una hoja de cálculo de Excel. Mi plan original era usar mi programa y ...

3  Raspador de noticias de Google para buscar enlaces con historias similares  ( Google news scraper to fetch links with similar stories ) 
El siguiente código lleva una URL o el título a un artículo de noticias existente. busca en Google News usando el título. recoge todos los enlaces de ...

1  Scraper de Python + Selenium para obtener resultados usando la búsqueda inversa  ( Python selenium scraper to grab results using reverse search ) 
He escrito algún código en Python en combinación con Selenium para raspar el resultado poblado de un sitio web después de realizar una búsqueda inversa. Mi ...

2  PHP Crawler para recoger comentarios sobre los artículos  ( Php crawler to collect comments on articles ) 
Tengo código que analiza las páginas web encuentra comentarios y guarda información sobre comentarios en DB. Tengo una matriz donde se almacenan todas las pág...

9  Un raspador web que busca palabras predefinidas en artículos de noticias  ( A web scraper that looks for pre defined words in news articles ) 
Sigo siendo bastante nuevo en Python y Web-rasping, pero un colega me preguntó si podía construir un raspador web que podría ser utilizado por un Think Tank, ...

2  Utilización de apiss de vapor y raspado web  ( Utilization of steam apis and web scraping ) 
alguna información de fondo aquí: Este es un pequeño proyecto divertido que hice utilizando las API de vapor y el raspado web Esta es la primera vez que ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos