Zhihu é uma verdadeira comunidade online de perguntas e respostas com uma atmosfera comunitária amigável, racional e séria que conecta elites de todas as esferas da vida. Eles compartilham conhecimento profissional, experiência e percepções uns dos outros e fornecem continuamente informações de alta qualidade para a Internet chinesa.
Primeiro, gaste de três a cinco minutos projetando um Logo =. =Como programador, sempre tive vontade de ser artista!
Ok, é um pouco improvisado, então vou me contentar com isso por enquanto.
Em seguida, começamos a fazer o rastreador de Zhihu.
Primeiro, determine o primeiro objetivo: recomendação do editor.
Link da web: http://www.zhihu.com/explore/recommendations
Modificamos ligeiramente o último código para primeiro conseguir obter o conteúdo da página:
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.zhihu.com/explore/recommendations";
//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(resultado);
}
}
Não há problema depois de executá-lo. A próxima etapa é um problema de correspondência regular.
Primeiro, vamos responder a todas as perguntas desta página.
Clique com o botão direito no título e inspecione o elemento:
Ah, você pode ver que o título é na verdade uma tag a, que é um hiperlink, e o que pode ser diferenciado de outros hiperlinks deve ser a classe, que é o seletor de classe.
Então, nossa declaração regular aparece: question_link.+?href=/"(.+?)/"
Chame a função RegexString e passe os parâmetros:
public static void main(String[] args) {
//Define o link a ser visitado
String url = "http://www.zhihu.com/explore/recommendations";
//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, "question_link.+?>(.+?)<");
// imprime resultados
System.out.println(imgSrc);
}
Ah ha, você pode ver que capturamos um título com sucesso (nota, apenas um):
Espere um minuto, o que é toda essa bagunça? !
Não fique nervoso=. =São apenas caracteres distorcidos.
Para problemas de codificação, consulte: Conjunto de caracteres HTML
De modo geral, as codificações convencionais com melhor suporte para chinês são as codificações UTF-8, GB2312 e GBK.
A página da web pode definir a codificação da página da web por meio do conjunto de caracteres da meta tag, por exemplo:
<meta charset="utf-8" />
Vamos clicar com o botão direito para visualizar o código-fonte da página:
Como você pode ver, Zhihu usa codificação UTF-8.
Aqui vou explicar a diferença entre visualizar o código fonte da página e inspecionar elementos.
Visualizar o código-fonte da página exibe todo o código da página inteira. Não é formatado de acordo com tags HTML. É equivalente a visualizar o código-fonte diretamente. Este método é mais útil para visualizar as informações de toda a página da web. meta.
Inspecione o elemento, ou alguns navegadores o chamam de elemento de visualização, que serve para visualizar o elemento em que você clica com o botão direito, como div ou img. É mais adequado para visualizar os atributos e tags de um objeto individualmente.
Pronto, agora que sabemos que o problema está na codificação, o próximo passo é converter a codificação do conteúdo capturado.
A implementação em java é muito simples, basta especificar o método de codificação em InputStreamReader:
//Inicializa o stream de entrada do BufferedReader para ler a resposta da URL
in = novo BufferedReader(novo InputStreamReader(
connection.getInputStream(),"UTF-8"));
Se você executar o programa novamente neste momento, verá que o título pode ser exibido normalmente:
OK! muito bom!
Mas agora só existe um título, precisamos de todos os títulos.
Modificamos ligeiramente a expressão regular e armazenamos os resultados pesquisados em um ArrayList:
importar java.io.*;
importar java.net.*;
importar java.util.ArrayList;
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(), "UTF-8"));
// 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;
}
static ArrayList<String> RegexString(String targetStr, String patternStr) {
// Pré-defina um ArrayList para armazenar os resultados
ArrayList<String> resultados = new ArrayList<String>();
// Define um modelo de estilo, utilizando expressões regulares, e o conteúdo a ser capturado fica entre parênteses
Padrão padrão = Pattern.compile(patternStr);
//Define um matcher para correspondência
Correspondente correspondente = pattern.matcher(targetStr);
// se encontrado
booleano isFind = matcher.find();
// Use um loop para encontrar e substituir todos os Kelvin na frase e adicionar o conteúdo a sb
enquanto (éEncontrar) {
//Adiciona resultados de correspondência bem-sucedidos
resultados.add(matcher.group(1));
//Continua para encontrar o próximo objeto correspondente
isFind = matcher.find();
}
retornar resultados;
}
public static void main(String[] args) {
//Define o link a ser visitado
String url = "http://www.zhihu.com/explore/recommendations";
//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
ArrayList<String> imgSrc = RegexString(resultado, "question_link.+?>(.+?)<");
// imprime resultados
System.out.println(imgSrc);
}
}
Isso corresponderá a todos os resultados (como ArrayList é impresso diretamente, haverá alguns colchetes e vírgulas):
OK, esta é a primeira etapa do rastreador Zhihu.
Mas podemos ver que não há como captar todas as perguntas e respostas desta forma.
Precisamos projetar uma classe de encapsulamento Zhihu para armazenar todos os objetos capturados.
Código-fonte Zhihu.java:
importar java.util.ArrayList;
classe pública Zhihu {
questão de String pública // pergunta
public String zhihuUrl; // link da página da Web
public ArrayList<String> respostas; // Array para armazenar todas as respostas;
//Construtor inicializa os dados
público Zhihu() {
pergunta = "";
zhihuUrl = "";
respostas = new ArrayList<String>();
}
@Substituir
string pública paraString() {
return "Pergunta:" + pergunta + "/nLink:" + zhihuUrl + "/nResposta:" + respostas + "/n";
}
}
Crie uma nova classe Spider para armazenar algumas funções de rastreadores comumente usadas.
Código-fonte Spider.java:
importar java.io.BufferedReader;
importar java.io.InputStreamReader;
importar java.net.URL;
importar java.net.URLConnection;
importar java.util.ArrayList;
importar java.util.regex.Matcher;
importar java.util.regex.Pattern;
classe pública Aranha {
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(), "UTF-8"));
// 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;
}
static ArrayList<Zhihu> GetZhihu(String conteúdo) {
// Pré-defina um ArrayList para armazenar os resultados
ArrayList<Zhihu> resultados = new ArrayList<Zhihu>();
// Usado para combinar títulos
Padrão questionPattern = Pattern.compile("question_link.+?>(.+?)<");
Correspondente questionMatcher = questionPattern.matcher(conteúdo);
// Usado para corresponder ao URL, que é o link para a pergunta
Padrão urlPattern = Pattern.compile("question_link.+?href=/"(.+?)/"");
Correspondente urlMatcher = urlPattern.matcher(conteúdo);
// Tanto a pergunta quanto o link devem corresponder
boolean isFind = questionMatcher.find() && urlMatcher.find();
enquanto (éEncontrar) {
//Define um objeto Zhihu para armazenar as informações capturadas
Zhihu zhuhuTemp = new Zhihu();
zhuhuTemp.question = questionMatcher.group(1);
zhuhuTemp.zhihuUrl = "http://www.zhihu.com" + urlMatcher.group(1);
//Adiciona resultados de correspondência bem-sucedidos
resultados.add(zhuhuTemp);
//Continua para encontrar o próximo objeto correspondente
isFind = questionMatcher.find() && urlMatcher.find();
}
retornar resultados;
}
}
O último método principal é responsável pela chamada.
importar java.util.ArrayList;
classe pública Principal {
public static void main(String[] args) {
//Define o link a ser visitado
String url = "http://www.zhihu.com/explore/recommendations";
//Acesse o link e obtenha o conteúdo da página
Conteúdo da string = Spider.SendGet(url);
// Obtém todos os objetos Zhihu nesta página
ArrayList<Zhihu> myZhihu = Spider.GetZhihu(conteúdo);
// imprime resultados
System.out.println(meuZhihu);
}
}
Ok, é isso. Execute-o e veja os resultados:
Bons resultados.
O próximo passo é acessar o link e obter todas as respostas.
Iremos apresentá-lo na próxima vez.
Ok, o texto acima é uma breve introdução a todo o processo de como usar Java para capturar conteúdo recomendado pelos editores da Zhihu. É muito detalhado e fácil de entender. Amigos necessitados podem consultá-lo e expandi-lo livremente, haha.