En el último episodio, hablamos sobre la necesidad de usar Java para crear un rastreador Zhihu, por lo que esta vez estudiaremos cómo usar código para obtener el contenido de la página web.
En primer lugar, si no tienes experiencia con HTML, CSS, JS y AJAX, se recomienda ir al W3C (haz clic en mí, haz clic en mí) para aprender un poco.
Hablando de HTML, esto implica un problema de acceso GET y acceso POST.
Si no comprende este aspecto, puede leer este artículo del W3C: "GET vs. POST".
Ajá, no entraré en detalles aquí.
Luego, a continuación necesitamos usar Java para rastrear el contenido de una página web.
En este momento, nuestro Baidu será útil.
Así es, ya no es el desconocido probador de velocidad de Internet, ¡está a punto de convertirse en nuestro conejillo de indias reptil! ~
Primero echemos un vistazo a la página de inicio de Baidu:
Creo que todo el mundo sabe que una página como ésta es el resultado del trabajo conjunto de HTML y CSS.
Hacemos clic derecho en la página en el navegador y seleccionamos "Ver código fuente de la página":
Así es, es algo como esto. Este es el código fuente de la página de Baidu.
Nuestra siguiente tarea es utilizar nuestro rastreador para obtener lo mismo.
Primero veamos un código fuente simple:
importar java.io.*;
importar java.net.*;
clase pública principal {
público estático vacío principal (String [] argumentos) {
//Definir el enlace a visitar
URL de cadena = "http://www.baidu.com";
//Definir una cadena para almacenar el contenido de la página web
Resultado de cadena = "";
//Definir un flujo de entrada de caracteres almacenado en buffer
BufferedReader en = nulo;
intentar {
//Convierte cadena en objeto URL
URL realUrl = nueva URL(url);
// Inicializa un enlace a esa URL
Conexión URLConnection = realUrl.openConnection();
// Iniciar la conexión real
conexión.connect();
//Inicializa el flujo de entrada BufferedReader para leer la respuesta de la URL
en = nuevo BufferedReader (nuevo InputStreamReader (
conexión.getInputStream()));
// Se utiliza para almacenar temporalmente los datos de cada fila capturada
Línea de cuerda;
mientras ((línea = in.readLine()) != nulo) {
//Recorre cada fila capturada y la almacena como resultado
resultado += línea;
}
} captura (Excepción e) {
System.out.println("¡Se produjo una excepción al enviar la solicitud GET!" + e);
e.printStackTrace();
}
// Usar finalmente para cerrar el flujo de entrada
finalmente {
intentar {
si (en! = nulo) {
cercar();
}
} captura (Excepción e2) {
e2.printStackTrace();
}
}
System.out.println(resultado);
}
}
Lo anterior es la simulación de Java para acceder al método principal de Baidu.
Puedes ejecutarlo para ver los resultados:
Ajá, es exactamente lo mismo que vimos antes en el navegador. En este punto, el rastreador más simple está listo.
Pero es posible que no todas esas cosas sean lo que quiero. ¿Cómo puedo obtener lo que quiero de ellas?
Tomemos como ejemplo el gran logotipo de la pata de Baidu.
Necesidades temporales:
Obtenga el enlace de la imagen de la gran pata del logotipo de Baidu.
Primero hablemos del método de visualización del navegador.
Haga clic derecho en la imagen y seleccione Inspeccionar elementos (Firefox, Google e IE11 tienen esta función, pero los nombres son diferentes):
Ajá, puedes ver la etiqueta img pobre rodeada de muchos divs.
Este src es el enlace a la imagen.
Entonces, ¿cómo lo hacemos en Java?
Tenga en cuenta de antemano que para facilitar la demostración del código, no todos los códigos están encapsulados por clases, por favor comprenda.
Primero encapsulemos el código anterior en una función sendGet:
importar java.io.*;
importar java.net.*;
clase pública principal {
Cadena estática sendGet (URL de cadena) {
//Definir una cadena para almacenar el contenido de la página web
Resultado de cadena = "";
//Definir un flujo de entrada de caracteres almacenado en buffer
BufferedReader en = nulo;
intentar {
//Convierte cadena en objeto URL
URL realUrl = nueva URL(url);
// Inicializa un enlace a esa URL
Conexión URLConnection = realUrl.openConnection();
// Iniciar la conexión real
conexión.connect();
//Inicializa el flujo de entrada BufferedReader para leer la respuesta de la URL
en = nuevo BufferedReader (nuevo InputStreamReader (
conexión.getInputStream()));
// Se utiliza para almacenar temporalmente los datos de cada fila capturada
Línea de cuerda;
mientras ((línea = in.readLine()) != nulo) {
// recorre cada fila capturada y la almacena como resultado
resultado += línea;
}
} captura (Excepción e) {
System.out.println("¡Se produjo una excepción al enviar la solicitud GET!" + e);
e.printStackTrace();
}
// Usar finalmente para cerrar el flujo de entrada
finalmente {
intentar {
si (en! = nulo) {
cercar();
}
} captura (Excepción e2) {
e2.printStackTrace();
}
}
resultado de devolución;
}
público estático vacío principal (String [] argumentos) {
//Definir el enlace a visitar
URL de cadena = "http://www.baidu.com";
//Accede al enlace y obtén el contenido de la página.
Resultado de cadena = enviarGet(url);
System.out.println(resultado);
}
}
Esto se ve un poco más ordenado, perdone mi trastorno obsesivo-compulsivo.
La siguiente tarea es encontrar el enlace a la imagen entre muchas cosas obtenidas.
El primer método que se nos ocurre es utilizar la función indexof para buscar subcadenas de cadena en la cadena de resultado del código fuente de la página.
Sí, este método puede resolver lentamente este problema, como indexOf ("src") directamente para encontrar el número de serie inicial y luego obtener el número de serie final rápidamente.
Sin embargo, no siempre podemos utilizar este método. Después de todo, las sandalias de paja solo son adecuadas para caminar. Más tarde, todavía tenemos que cortar las piernas ortopédicas para sujetar las cabezas.
Por favor, perdone mi intrusión y continúe.
Entonces, ¿cómo encontramos el src de esta imagen?
Así es, como dijo la audiencia a continuación, coincidencia regular.
Si algún estudiante no está seguro acerca de las expresiones regulares, puede consultar este artículo: [Python] Web Crawler (7): Tutorial de expresiones regulares en Python.
En pocas palabras, la expresión regular es como hacer coincidir.
Por ejemplo, aquí hay tres hombres gordos, vestidos con ropa roja, ropa azul y ropa verde.
La regla es: ¡atrapa al que está en verde!
Luego atrapó solo al gordo hombre verde.
Es así de simple.
Sin embargo, la gramática habitual sigue siendo extensa y profunda, y es inevitable que te sientas un poco confundido cuando entres en contacto con ella por primera vez.
Recomiendo a todos una herramienta de prueba en línea habitual: pruebas en línea de expresiones regulares.
Con la regularidad como arma mágica, ¿cómo utilizar la regularidad en Java?
Veamos primero una ciruela pequeña y sencilla.
Ah, mal, castaña.
//Definimos una plantilla de estilo, usando expresiones regulares, y el contenido a capturar está entre paréntesis
// Equivale a enterrar una trampa y caerá si coincide.
Patrón patrón = Pattern.compile("href=/"(.+?)/"");
//Definir un comparador para hacer coincidir
Matcher matcher = patrón.matcher("<a href=/"index.html/">Mi página de inicio</a>");
// si se encuentra
si (matcher.find()) {
//imprime el resultado
System.out.println(matcher.group(1));
}
Resultados de ejecución:
índice.html
Sí, este es nuestro primer código normal.
El enlace para tomar fotografías en esta aplicación debe estar a su alcance.
Encapsulamos la coincidencia regular en una función y luego modificamos el código de la siguiente manera:
importar java.io.*;
importar java.net.*;
importar java.util.regex.*;
clase pública principal {
Cadena estática SendGet (URL de cadena) {
//Definir una cadena para almacenar el contenido de la página web
Resultado de cadena = "";
//Definir un flujo de entrada de caracteres almacenado en buffer
BufferedReader en = nulo;
intentar {
//Convierte cadena en objeto URL
URL realUrl = nueva URL(url);
// Inicializa un enlace a esa URL
Conexión URLConnection = realUrl.openConnection();
// Iniciar la conexión real
conexión.connect();
//Inicializa el flujo de entrada BufferedReader para leer la respuesta de la URL
en = nuevo BufferedReader (nuevo InputStreamReader (
conexión.getInputStream()));
// Se utiliza para almacenar temporalmente los datos de cada fila capturada
Línea de cuerda;
mientras ((línea = in.readLine()) != nulo) {
// recorre cada fila capturada y la almacena como resultado
resultado += línea;
}
} captura (Excepción e) {
System.out.println("¡Se produjo una excepción al enviar la solicitud GET!" + e);
e.printStackTrace();
}
// Usar finalmente para cerrar el flujo de entrada
finalmente {
intentar {
si (en! = nulo) {
cercar();
}
} captura (Excepción e2) {
e2.printStackTrace();
}
}
resultado de devolución;
}
cadena estática RegexString (cadena targetStr, cadena patrónStr) {
//Definimos una plantilla de estilo, usando expresiones regulares, y el contenido a capturar está entre paréntesis
// Equivale a enterrar una trampa y caerá si coincide.
Patrón patrón = Pattern.compile(patternStr);
//Definir un comparador para hacer coincidir
Comparador de coincidencias = patrón.matcher(targetStr);
// si se encuentra
si (matcher.find()) {
//imprime el resultado
devolver matcher.group(1);
}
devolver "";
}
público estático vacío principal (String [] argumentos) {
//Definir el enlace a visitar
URL de cadena = "http://www.baidu.com";
//Accede al enlace y obtén el contenido de la página.
Resultado de cadena = SendGet(url);
// Usa expresiones regulares para hacer coincidir el contenido src de la imagen
String imgSrc = RegexString(resultado, "Próxima gramática regular");
// imprimir resultados
System.out.println(imgSrc);
}
}
Bien, ahora todo está listo, ¡solo una gramática normal!
Entonces, ¿qué afirmación habitual es más apropiada?
Descubrimos que siempre que tomemos la cadena src="xxxxxx", podemos tomar el enlace src completo.
Entonces, una declaración regular simple: src=/"(.+?)/"
El código completo es el siguiente:
importar java.io.*;
importar java.net.*;
importar java.util.regex.*;
clase pública principal {
Cadena estática SendGet (URL de cadena) {
//Definir una cadena para almacenar el contenido de la página web
Resultado de cadena = "";
//Definir un flujo de entrada de caracteres almacenado en buffer
BufferedReader en = nulo;
intentar {
//Convierte cadena en objeto URL
URL realUrl = nueva URL(url);
// Inicializa un enlace a esa URL
Conexión URLConnection = realUrl.openConnection();
// Iniciar la conexión real
conexión.connect();
//Inicializa el flujo de entrada BufferedReader para leer la respuesta de la URL
en = nuevo BufferedReader (nuevo InputStreamReader (
conexión.getInputStream()));
// Se utiliza para almacenar temporalmente los datos de cada fila capturada
Línea de cuerda;
mientras ((línea = in.readLine()) != nulo) {
// recorre cada fila capturada y la almacena como resultado
resultado += línea;
}
} captura (Excepción e) {
System.out.println("¡Se produjo una excepción al enviar la solicitud GET!" + e);
e.printStackTrace();
}
// Usar finalmente para cerrar el flujo de entrada
finalmente {
intentar {
si (en! = nulo) {
cercar();
}
} captura (Excepción e2) {
e2.printStackTrace();
}
}
resultado de devolución;
}
cadena estática RegexString (cadena targetStr, cadena patrónStr) {
//Definimos una plantilla de estilo, usando expresiones regulares, y el contenido a capturar está entre paréntesis
// Equivale a enterrar una trampa y caerá si coincide.
Patrón patrón = Pattern.compile(patternStr);
//Definir un comparador para hacer coincidir
Comparador de coincidencias = patrón.matcher(targetStr);
// si se encuentra
si (matcher.find()) {
//imprime el resultado
devolver matcher.group(1);
}
devolver "Nada";
}
público estático vacío principal (String [] argumentos) {
//Definir el enlace a visitar
URL de cadena = "http://www.baidu.com";
//Accede al enlace y obtén el contenido de la página.
Resultado de cadena = SendGet(url);
// Usa expresiones regulares para hacer coincidir el contenido src de la imagen
String imgSrc = RegexString(resultado, "src=/"(.+?)/"");
// imprimir resultados
System.out.println(imgSrc);
}
}
De esta manera, podemos usar Java para obtener el enlace al logotipo de Baidu.
Bueno, aunque he pasado mucho tiempo hablando de Baidu, las bases deben estar sólidas. ¡La próxima vez comenzaremos oficialmente a centrarnos en Zhihu! ~