No último episódio falamos sobre a necessidade de usar Java para fazer um rastreador Zhihu, então desta vez estudaremos como usar o código para obter o conteúdo da página web.
Primeiramente, se você não tem experiência com HTML, CSS, JS e AJAX, é recomendado ir ao W3C (clique em mim, clique em mim) para aprender um pouco.
Falando em HTML, isso envolve um problema de acesso GET e acesso POST.
Se você não entende esse aspecto, pode ler este artigo do W3C: "GET vs. POST".
Ah, não vou entrar em detalhes aqui.
Em seguida, precisamos usar Java para rastrear o conteúdo de uma página da web.
Neste momento, nosso Baidu será útil.
É isso mesmo, ele não é mais o desconhecido testador de velocidade da Internet, ele está prestes a se tornar nossa cobaia réptil! ~
Vamos primeiro dar uma olhada na página inicial do Baidu:
Acredito que todos sabem que uma página como essa é resultado do trabalho conjunto de HTML e CSS.
Clicamos com o botão direito na página no navegador e selecionamos "Exibir código-fonte da página":
Isso mesmo, é algo assim. Este é o código-fonte da página do Baidu.
Nossa próxima tarefa é usar nosso rastreador para obter a mesma coisa.
Vejamos primeiro um código-fonte simples:
importar java.io.*;
importar java.net.*;
classe pública Principal {
public static void main(String[] args) {
//Define o link a ser visitado
String url = "http://www.baidu.com";
//Define uma string para armazenar o conteúdo da página web
Resultado da string = "";
//Define um fluxo de entrada de caracteres em buffer
BufferedReader em = null;
tentar {
//Converte string em objeto url
URL realUrl = nova URL(url);
// Inicializa um link para essa URL
Conexão URLConnection = realUrl.openConnection();
// Inicia a conexão real
conexão.connect();
//Inicializa o stream de entrada do BufferedReader para ler a resposta da URL
in = novo BufferedReader(novo InputStreamReader(
connection.getInputStream()));
// Usado para armazenar temporariamente os dados de cada linha capturada
Linha de corda;
while ((linha = in.readLine()) != null) {
//Percorre cada linha capturada e armazena-a no resultado
resultado += linha;
}
} catch (Exceção e) {
System.out.println("Ocorreu exceção ao enviar solicitação GET!" + e);
e.printStackTrace();
}
// Use finalmente para fechar o fluxo de entrada
finalmente {
tentar {
if (em! = nulo) {
in.close();
}
} catch (Exceção e2) {
e2.printStackTrace();
}
}
System.out.println(resultado);
}
}
A descrição acima é a simulação Java de Get acessando o método Main do Baidu.
Você pode executá-lo para ver os resultados:
Aha, é exatamente igual ao que vimos no navegador anteriormente. Neste ponto, o rastreador mais simples está pronto.
Mas uma pilha tão grande de coisas pode não ser tudo o que eu quero. Como posso conseguir o que quero?
Veja o logotipo da pata grande do Baidu como exemplo.
Necessidades temporárias:
Obtenha o link da imagem da pata grande do logotipo do Baidu.
Vamos primeiro falar sobre o método de visualização do navegador.
Clique com o botão direito na imagem e selecione Inspecionar Elementos (Firefox, Google e IE11 têm essa função, mas os nomes são diferentes):
Aha, você pode ver a pobre tag img cercada por muitos divs.
Este src é o link para a imagem.
Então, como fazemos isso em java?
Observe com antecedência que, para facilitar a demonstração do código, todos os códigos não são encapsulados por classes, por favor, entenda.
Vamos primeiro encapsular o código anterior em uma função sendGet:
importar java.io.*;
importar java.net.*;
classe pública Principal {
String estática sendGet(String url) {
//Define uma string para armazenar o conteúdo da página web
Resultado da string = "";
//Define um fluxo de entrada de caracteres em buffer
BufferedReader em = null;
tentar {
//Converte string em objeto url
URL realUrl = nova URL(url);
// Inicializa um link para essa URL
Conexão URLConnection = realUrl.openConnection();
// Inicia a conexão real
conexão.connect();
//Inicializa o fluxo de entrada do BufferedReader para ler a resposta da URL
in = novo BufferedReader(novo InputStreamReader(
connection.getInputStream()));
// Usado para armazenar temporariamente os dados de cada linha capturada
Linha de corda;
while ((linha = in.readLine()) != null) {
// Percorre cada linha capturada e armazena-a no resultado
resultado += linha;
}
} catch (Exceção e) {
System.out.println("Ocorreu exceção ao enviar solicitação GET!" + e);
e.printStackTrace();
}
// Use finalmente para fechar o fluxo de entrada
finalmente {
tentar {
if (em! = nulo) {
in.close();
}
} catch (Exceção e2) {
e2.printStackTrace();
}
}
resultado de retorno;
}
public static void main(String[] args) {
//Define o link a ser visitado
String url = "http://www.baidu.com";
//Acesse o link e obtenha o conteúdo da página
String resultado = sendGet(url);
System.out.println(resultado);
}
}
Isto parece um pouco mais arrumado, por favor, perdoe meu transtorno obsessivo-compulsivo.
A próxima tarefa é encontrar o link para a imagem entre muitas coisas obtidas.
O primeiro método que podemos pensar é usar a função indexof para procurar substrings String no resultado da string do código-fonte da página.
Sim, este método pode resolver esse problema lentamente, como indexOf("src") diretamente para encontrar o número de série inicial e, em seguida, obter o número de série final rapidamente.
Porém, nem sempre podemos usar esse método. Afinal, sandálias de palha só servem para passear. Depois, ainda precisamos cortar as pernas protéticas para segurar as cabeças.
Por favor, perdoe minha intrusão e continue.
Então, como encontramos o src desta imagem?
Isso mesmo, como disse o público abaixo, correspondência regular.
Se algum aluno não tiver certeza sobre expressões regulares, consulte este artigo: [Python] Web Crawler (7): Tutorial de expressões regulares em Python.
Simplificando, regex é como combinar.
Por exemplo, três homens gordos estão parados aqui, vestindo roupas vermelhas, azuis e verdes.
A regra é: pegue aquele de verde!
Então ele pegou o gordo homem verde sozinho.
É tão simples.
Porém, a gramática regular ainda é extensa e profunda, e é inevitável que você fique um pouco confuso ao entrar em contato com ela pela primeira vez.
Eu recomendo uma ferramenta de teste online regular para todos: testes online de expressão regular.
Tendo a regularidade como arma mágica, como usar a regularidade em java?
Vejamos primeiro uma pequena ameixa simples.
Ah, errado, pequena castanha.
// Define um modelo de estilo, utilizando expressões regulares, e o conteúdo a ser capturado fica entre parênteses
// É equivalente a enterrar uma armadilha e ela cairá se corresponder.
Padrão padrão = Pattern.compile("href=/"(.+?)/"");
//Define um matcher para correspondência
Matcher matcher = pattern.matcher("<a href=/"index.html/">Minha página inicial</a>");
// se encontrado
if (matcher.find()) {
//imprime o resultado
System.out.println(matcher.group(1));
}
Resultados em execução:
index.html
Sim, este é o nosso primeiro código regular.
O link para capturar fotos neste aplicativo deve estar ao seu alcance.
Encapsulamos a correspondência regular em uma função e, em seguida, modificamos o código da seguinte maneira:
importar java.io.*;
importar java.net.*;
importar java.util.regex.*;
classe pública Principal {
String estática SendGet(String url) {
//Define uma string para armazenar o conteúdo da página web
Resultado da string = "";
//Define um fluxo de entrada de caracteres em buffer
BufferedReader em = null;
tentar {
//Converte string em objeto url
URL realUrl = nova URL(url);
// Inicializa um link para essa URL
Conexão URLConnection = realUrl.openConnection();
// Inicia a conexão real
conexão.connect();
//Inicializa o stream de entrada do BufferedReader para ler a resposta da URL
in = novo BufferedReader(novo InputStreamReader(
connection.getInputStream()));
// Usado para armazenar temporariamente os dados de cada linha capturada
Linha de corda;
while ((linha = in.readLine()) != null) {
// Percorre cada linha capturada e armazena-a no resultado
resultado += linha;
}
} catch (Exceção e) {
System.out.println("Ocorreu exceção ao enviar solicitação GET!" + e);
e.printStackTrace();
}
// Use finalmente para fechar o fluxo de entrada
finalmente {
tentar {
if (em! = nulo) {
in.close();
}
} catch (Exceção e2) {
e2.printStackTrace();
}
}
resultado de retorno;
}
String estática RegexString (String targetStr, String patternStr) {
// Define um modelo de estilo, utilizando expressões regulares, e o conteúdo a ser capturado fica entre parênteses
// É equivalente a enterrar uma armadilha e ela cairá se corresponder.
Padrão padrão = Pattern.compile(patternStr);
//Define um matcher para correspondência
Correspondente correspondente = pattern.matcher(targetStr);
// se encontrado
if (matcher.find()) {
//imprime o resultado
retornar matcher.grupo(1);
}
retornar "";
}
public static void main(String[] args) {
//Define o link a ser visitado
String url = "http://www.baidu.com";
//Acesse o link e obtenha o conteúdo da página
String resultado = SendGet(url);
// Use expressões regulares para corresponder ao conteúdo src da imagem
String imgSrc = RegexString(resultado, "Próxima gramática regular");
// imprime resultados
System.out.println(imgSrc);
}
}
Pronto, agora está tudo pronto, apenas uma gramática normal!
Então, qual declaração regular é mais apropriada?
Descobrimos que, contanto que peguemos a string src="xxxxxx", podemos pegar o link src inteiro.
Portanto, uma instrução regular simples: src=/"(.+?)/"
O código completo é o seguinte:
importar java.io.*;
importar java.net.*;
importar java.util.regex.*;
classe pública Principal {
String estática SendGet(String url) {
//Define uma string para armazenar o conteúdo da página web
Resultado da string = "";
//Define um fluxo de entrada de caracteres em buffer
BufferedReader em = null;
tentar {
//Converte string em objeto url
URL realUrl = nova URL(url);
// Inicializa um link para essa URL
Conexão URLConnection = realUrl.openConnection();
// Inicia a conexão real
conexão.connect();
//Inicializa o stream de entrada do BufferedReader para ler a resposta da URL
in = novo BufferedReader(novo InputStreamReader(
connection.getInputStream()));
// Usado para armazenar temporariamente os dados de cada linha capturada
Linha de corda;
while ((linha = in.readLine()) != null) {
// Percorre cada linha capturada e armazena-a no resultado
resultado += linha;
}
} catch (Exceção e) {
System.out.println("Ocorreu exceção ao enviar solicitação GET!" + e);
e.printStackTrace();
}
// Use finalmente para fechar o fluxo de entrada
finalmente {
tentar {
if (em! = nulo) {
in.close();
}
} catch (Exceção e2) {
e2.printStackTrace();
}
}
resultado de retorno;
}
String estática RegexString (String targetStr, String patternStr) {
// Define um modelo de estilo, utilizando expressões regulares, e o conteúdo a ser capturado fica entre parênteses
// É equivalente a enterrar uma armadilha e ela cairá se corresponder.
Padrão padrão = Pattern.compile(patternStr);
//Define um matcher para correspondência
Correspondente correspondente = pattern.matcher(targetStr);
// se encontrado
if (matcher.find()) {
//imprime o resultado
retornar matcher.grupo(1);
}
retorne "Nada";
}
public static void main(String[] args) {
//Define o link a ser visitado
String url = "http://www.baidu.com";
//Acesse o link e obtenha o conteúdo da página
String resultado = SendGet(url);
// Use expressões regulares para corresponder ao conteúdo src da imagem
String imgSrc = RegexString(resultado, "src=/"(.+?)/"");
// imprime resultados
System.out.println(imgSrc);
}
}
Desta forma, podemos usar java para obter o link para o Baidu LOGO.
Bem, embora eu tenha passado muito tempo falando sobre o Baidu, as bases devem ser estabelecidas de forma sólida. Da próxima vez, começaremos oficialmente a nos concentrar em Zhihu! ~