웹 캡처com.NET Core 3.1
35855 단어 webscrapingdotnet
Para examplicar aqui,vamos acessar o sitepensador.com,e recurparar as citaões que ficam disponíveis Para visualizaço.Nosso objetivo entãoérecurparar as citaões de um determinado autor ou tema e armazenarmos em Nosso dispositivo.
Cria ão do projeto 프로젝트
Minha necessidade era construir esse banco de citaçes uma vez,sem a necessidade ficar atualizando ou ter algum acesso remoto.Por este motivo decidi criar uma aplicaão de linha de comando,para isso utilizei o próprio template disponibilizado pelo Visual Studio.
Após nomer o projeto e realizar sua criaão,énecesário installar o pacote AngleSharp como uma dependencia do projeto.Para issoénecessário clicar com o botão direito do mouse em“Dependencies”,e selecionar a opão“Manage NuGet Packages”.Vocêdeve visualizar uma tela semelhante com a imagem abaixo:
Após clicar em instalar,nosso projeto estápronto para começarmos a realizar chamadas ao site.
Acessando 장소
Poderíamos realizar as chamadas diretamente no método Main da aplicaão,mas eu prefiro separar em classes differentes algumas operaçes.Sendo assim,decidi criar uma pasta Services e criar uma classe
ScrapperService.cs
dentro.Essa seráa classe responsável por acessar o site que desejamos e trazer nossos dados jámodelados.Nessa classe
ScrapperService.cs
vamos criar uma propriedade do tipoIBrowsingContext
,queéuma interface do pacote AngleSharp,que seráresponsável por fazer a requisiçoás páginas web que desejamos acessar.A classe junto com o seu construtor ficaráassim:using AngleSharp;
namespace PensadorScrapper.Services
{
class ScrapperService
{
private IBrowsingContext context { get; set; }
public ScrapperService()
{
var config = Configuration.Default.WithDefaultLoader();
context = BrowsingContext.New(config);
}
}
}
Nessa etapa jápodemos escrever o método que irárealizar a leitura dos nossos dados de intereste,mas anteséimportant abrirmos a página em nosso navegador para vermos como o DOM estáorganizado,para então organizarmos nossa estrate gia de obtenãdos dados.ao abrir a página inicial de algum tema de intereste podemos perceber a organization ao da página.Vou usar como Examplo cita es com o tema de filosofia, página pode ser visualizada abaixo:Ao analisarmos dessa forma,conseguimos visualizar onde estão os elementos de interestse para nossa aplicaão,que são:as citaões e número total de citaçes.필요성 검증 o n úmero total de cita es para podermos calcular o n úmero de páginas estimado que cada tema ou autor terá.아심,conseguiremosextrair todas as cita es de cadaum.
Após a análise visualénecesário verificiar a organizaão do documento HTML,como jásabemos nossos elementos de intereste,podemos clicar com o botão direito e inspeciator o elemento para irmos direto a ele no código.Verificando o elemento,podemos então clicar com o botão direito novate e selecionar a opão de copiar seletor.Esse caminhoéque utilizaremos para encontrar Esse elemento em nossa aplicaão com o AngleSharp,então guarde ele em algum lugar.Abaixo uma imagem examplificando o que foi realizado.
Realizando a mesma etapa para o bloco das citaçes,temos dois seletores copiados:
ScrapperService.cs
,o método fica assim:public async IAsyncEnumerable<Quote> GetQuotes(string assunto, int pagina)
{
var url = $"https://www.pensador.com/{assunto}/{pagina}";
Console.WriteLine(url);
var document = await context.OpenAsync(url);
var quotesHtml = document.QuerySelectorAll("#content > div.phrases-list > .thought-card");
foreach (var item in quotesHtml)
{
var autor = item.QuerySelector(".autor").Text();
int id = int.Parse(item.GetAttribute("data-id"));
var texto = item.QuerySelector(".frase").Text();
if(item.QuerySelector(".insert-onlist") != null)
{
continue;
}
yield return new Quote(id, autor.Trim(), texto.Trim());
}
}
설명 o c ó digo acima:Montamos então a url de acesso concatenando os textos conforme o padrão que o site utiliza,queéalgum desses dois:
var document = await context.OpenAsync(url);
éque realizamos a leitura do documento,com auxilio do pacote AngleSharp.Esse método nos returna um objeto com a página mapeada ondeépossível navegar através dos seus nós.Como jáhavíamos anotado nossos seletores,podemos utilizar a funão queryselectoral para returnar os nós de interest nese documento.Para isso então passamos o nosso seletor de todas as citaçes como par–metro,adicionado da classe que todas citaçes comparitilham em comum,como pode ser observado abaixo:
var quotesHtml = document.QuerySelectorAll("#content > div.phrases-list > .thought-card");
Quote.cs
,que pode ser visualizada abaixo:namespace PensadorScrapper.Models
{
class Quote
{
public int Id { get; set; }
public string Autor { get; set; }
public string Texto { get; set; }
public Quote(int id, string autor, string texto)
{
Id = id;
Autor = autor;
Texto = texto;
}
}
}
yield
,que farácom que as citaçes sejam retronadas assim que forem sendo recuperadas do site.E como descobrimos quantas páginas existem?
Se nós chamarmos o método construído acima,nossa aplicaão jávai Returnar todas citaçes de cada página que passarmos como par–metro.páginas deum tema ou autor로서 당신은 누구입니까?Para isso que salvamos o seletor daquela parte da página que nos informava o número total de posts.Porém,se analisarmos outra página,de algum autor Escífico,Por Examplo,veremos que algumas informaçes estão Differentes:
O site pensador,quando tem um artista famoso,muda O texto de total de citaçes,e também muda a estrutura do HTML,para isso entãO precisamos mapear esse seletor também.Logo,temos dois seletores distintos:
public async Task<int> GetTotalPages(string assunto)
{
var document = await context.OpenAsync($"https://www.pensador.com/{assunto}");
var quotesHtml = document.QuerySelectorAll("#content > div.phrases-list > .thought-card");
var textoTotal = "";
int quantidadePorPagina;
int total;
if (document.QuerySelector("#content > div.top > div.total") != null)
{
textoTotal = document.QuerySelector("#content > div.top > div.total").Text();
if (int.TryParse(Regex.Match(textoTotal, @"(?<=de )(.*)(?= pensamentos )").Value, out total))
{
quantidadePorPagina = int.Parse(Regex.Match(textoTotal, @"(?<=-\n)(.\d)(?=)").Value);
total = int.Parse(Regex.Match(textoTotal, @"(?<=de )(.*)(?= pensamentos )").Value);
}
else
{
total = int.Parse(Regex.Replace(textoTotal, @"[^\d]", ""));
quantidadePorPagina = quotesHtml.Count();
}
}
else
{
total = int.Parse(document.QuerySelector("#content > div.autorTotal > strong:nth-child(2)").Text());
var textoPagina = document.QuerySelector("#content > div.autorTotal > strong:nth-child(1)").Text();
quantidadePorPagina = int.Parse(Regex.Match(textoPagina, @"(?<= )(.\d)(?=)").Value);
}
int paginas = total / quantidadePorPagina;
Console.WriteLine("Total: " + total);
Console.WriteLine("Paginas: " + paginas);
return paginas;
}
Esse método ficou um pouco extenso,e poderia ser otimizado,mas deixaremos para fazer isso em uma segunda versão.para extrair as informaões de total de citaões e paginaço utilizei Regex.Explicando de uma forma geral,o método acessa a primeira página do autor ou tema e verifica se estáno padrão de totais de citaão tema ou autor,então utiliza as técnicas de QuerySelector para realizar a captura dos nós.Após isso,o valor total de citaõesédividido pela quantidade citaões por página e armazenado em um inteiro para arredonddarmos para baixo o total de páginas.Acessando todas páginas de um tema Escífico ou autor
Agora que jápossuímos um método para estimar o número total de páginas e outro método para buscar as citaões dessa página,sónecessamos realizar um laço de repetião alterando a página atéo total de página daquele autor ou tema.Para isso,podemos adicionar em nosso método Main da classe
Program.cs
.1 레벨 fica ASIM:using PensadorScrapper.Services;
using System;
namespace PensadorScrapper
{
class Program
{
static async System.Threading.Tasks.Task Main(string[] args)
{
ScrapperService scrapper = new ScrapperService();
string assunto = "autor/william_shakespeare";
Console.WriteLine($"\n\n\n\n\n\nAUTOR: william_shakespeare \n\n\n");
var totalPaginas = await scrapper.GetTotalPages(assunto);
Console.WriteLine("N de paginas: " + totalPaginas);
for (var i = 1; i <= totalPaginas; i++)
{
await foreach (var quote in scrapper.GetQuotes(assunto, i))
{
Console.WriteLine($"ID: {quote.Id} | Autor: {quote.Autor.Trim()} | Frase: {quote.Texto.Trim()}");
}
Console.WriteLine($"\n --------Página {i}--------- \n\n");
}
}
}
}
Ao executarmos o código podemos ver como estáfuncionando nossa aplicaão:Ainda,se desejarmos buscar dados de mais de um autor ou tema poderíamos criar uma Lista de autores e iterar sobre ela chamando os nossos mesmos métodos,dessa maneira:
using PensadorScrapper.Models;
using PensadorScrapper.Services;
using System;
using System.Collections.Generic;
namespace PensadorScrapper
{
class Program
{
static async System.Threading.Tasks.Task Main(string[] args)
{
ScrapperService scrapper = new ScrapperService();
List<string> autores = new List<string>{
"jean_jacques_rousseau",
"rene_descartes",
"immanuel_kant",
"john_locke",
"blaise_pascal",
"galileu_galilei",
"michel_de_montaigne",
"mary_wollstonecraft",
"angela_davis",
"hipatia_de_alexandria",
"maquiavel",
"adam_smith",
"zygmunt_bauman",
"baruch_espinosa",
"friedrich_engels",
"georg_wilhelm_friedrich_hegel",
"soren_kierkegaard",
"epicteto",
"martin_heidegger",
"michel_foucault",
"martin_heidegger",
"hannah_arendt"
};
foreach (var autor in autores)
{
string assunto = "autor/"+autor;
Console.WriteLine($"\n\n\n\n\n\nAUTOR: {autor} \n\n\n");
var totalPaginas = await scrapper.GetTotalPages(assunto);
Console.WriteLine("N de paginas: " + totalPaginas);
for (var i = 1; i <= totalPaginas; i++)
{
await foreach (var quote in scrapper.GetQuotes(assunto, i))
{
Console.WriteLine($"ID: {quote.Id} | Autor: {quote.Autor.Trim()} | Frase: {quote.Texto.Trim()}");
QuotesRepository.SaveQuote(quote);
}
Console.WriteLine($"\n --------Página {i}--------- \n\n");
}
}
}
}
}
결론
당장!Temos uma aplicaão que realiza um Web Scraping no site pensador.com e returna todas as citaçes disponíveis de um determinado autor ou tema.Claro que normalmente nãoésóisso que desejamos.Muitas vezes essidamos armazenar essas informaçes.Por esse motivo eu járealizei também a integraço dessa aplicaço com um banco de dados,onde essas informaçes ficam armazenadas.Mas como o post jáficou extenso,vou tratar desta etapa em um outro post aqui.Utilizaremos SQLite para armazenar e recurper esses dados.O código completo desse post,com a versãO jáutilizando banco de dados pode ser encontrado no meuGithub.Abaixo temos um GIF da aplicaão funcionando:
Reference
이 문제에 관하여(웹 캡처com.NET Core 3.1), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/lucaspsilveira/web-scrapping-com-net-core-3-1-228m텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)