Lógica para implementar um raspador dinâmico da Web em C#
-
22-09-2019 - |
Pergunta
Estou procurando desenvolver um raspador da web em formulários de janela C#. O que estou tentando realizar é o seguinte:
- Obtenha o URL do usuário.
- Carregue a página da web no IE UI Control (navegador incorporado) no WinForms.
- Permita que o usuário selecione um texto (contíguo, pequeno (não superior a 50 chars)). Na página da web carregada.
- Quando o usuário deseja persistir o local (A localização html dom) ele deve ser persistido no banco de dados, para que o usuário possa usar esse local para buscar os dados nesse local durante suas visitas subsequentes.
Suponha que o site carregado seja um site de pré -lista e a taxa cotada continua mudando, a idéia é persistir a hierarquia do DOM para que eu possa atravessá -la na próxima vez.
Eu seria capaz de fazer isso se todos os elementos HTML tivessem seus atributos de ID. No caso em que o ID é nulo, não consigo conseguir isso.
Alguém poderia sugerir uma idéia válida sobre isso (um trecho de código mínimo, se possível).
Seria útil, mesmo que você pudesse compartilhar alguns recursos on -line.
obrigado,
Vijay
Solução
Uma abordagem é criar uma pilha de tags/estilos/id para o elemento que você deseja selecionar.
Do elemento que você deseja, atravesse o elemento de identificação mais próximo. Dessa forma, você se livrará da maioria do cabeçalho superior etc. Em seguida, construa uma sequência para procurar.
Exemplo:
<html>
<body>
<!-- lots of html -->
<div id="main">
<div>
<span>
<div class="pricearea">
<table> <!-- with price data -->
Para o exmaple que você armazenaria em seu banco de dados uma sequência de: id = main], div, span, div, tabela ou talvez div [class = Pricearea], tabela.
Usar estilos/classes também pode ser usado para criar seu caminho. É sua escolha procurar uma tag, um atributo de uma tag ou uma combinação. Você o quer o mais preciso possível com o menor número possível de elementos para torná -lo robusto.
Se o layout raramente mudar, isso permitirá que você navegue para o mesmo local a cada vez.
Eu também sugeriria que você use HTML Agility Pack Ou algo semelhante para a análise DOM, pois o controle do IE é lento.
A raspagem da tela é divertida, mas é difícil obtê -lo 100% para todas as páginas. Boa sorte!
Outras dicas
Depois de um pouco de Google, encontrei uma solução bastante simples. Abaixo anexado está o snippet de amostra.
if (webBrowser.Document != null)
{
IHTMLDocument2 HtmlDoc = (IHTMLDocument2)webBrowser.Document.DomDocument;// loads the HTML DOM
IHTMLSelectionObject selection = HtmlDoc.selection;// Fetches the currently selected HTML Element.
IHTMLTxtRange range = (IHTMLTxtRange)selection.createRange();
IHTMLElement parentElement = range.parentElement();// Identifies the parent element
targetSourceIndex = parentElement.sourceIndex;
//dataLocation = range.parentElement().id;
MessageBox.Show(range.text);//range.parentElement().sourceIndex
}
Eu usei um Navegador da web incorporado Em um aplicativo WinForms, que carrega o HTML DOM da página da web atual.
o Ihtmlelement A instância expõe uma propriedade chamada 'SourceIndex', que aloca um ID exclusivo para cada um dos elementos HTML.
Pode -se armazenar esse fonte no banco de dados e consultar o conteúdo nesse local. usando o seguinte código.
if (webBrowser.Document != null)
{
IHTMLDocument2 HtmlDoc = (IHTMLDocument2)webBrowser.Document.DomDocument;
IHTMLElement targetElement = null;
foreach (IHTMLElement domElement in HtmlDoc.all)
{
if (domElement.sourceIndex == int.Parse(node.InnerText))// fetching the persisted data from the XML file.
{
targetElement = domElement;
break;
}
}
MessageBox.Show(targetElement.innerText); //range.parentElement().sourceIndex
}