Qual é a melhor maneira de extrair dados de um site? [fechadas]

107

Preciso extrair conteúdo de um site, mas o aplicativo não fornece nenhuma interface de programação de aplicativo ou outro mecanismo para acessar esses dados programaticamente.

Encontrei uma ferramenta de terceiros útil chamada Import.io que fornece funcionalidade click and go para copiar páginas da web e construir conjuntos de dados, a única coisa é que quero manter meus dados localmente e não quero assinar nenhum plano de assinatura .

Que tipo de técnica esta empresa usa para raspar as páginas da web e construir seus conjuntos de dados? Eu encontrei alguns frameworks de web scrape pjscrape & Scrapy; eles poderiam fornecer tal recurso

0x1ad2
fonte
4
PHP certamente não está fora de questão, isso é totalmente errado, obviamente. gist.github.com/krakjoe/b1526fcc828621e840cb
Joe Watkins
@JoeWatkins que parece muito legal, ela precisa de uma configuração especial do PHP para rodar? E como é o desempenho em comparação com as ferramentas / linguagens fornecidas abaixo?
0x1ad2
1
Requer uma construção segura de thread de PHP, e pthreads, leia github.com/krakjoe/pthreads/blob/master/README.md , você pode me encontrar no chat se quiser ajuda, eu ou qualquer outra pessoa :)
Joe Watkins
@ 0x1ad2 Se você deseja manter os dados localmente, deve tentar o software ( datascraping.co ) em vez das APIs da Web. A maioria das ferramentas usa Xpath, CSS selector e REGEX para extrair os dados de sites e o Data Scraping Studio suporta todos esses 3 recursos.
Vikash Rathee
Há duas maneiras, uma é implantar seu próprio usando bibliotecas de código aberto / gratuitas, o que exige muito esforço. Você pode gerar literalmente um rastreador ajax para qualquer site usando scrape.it. É uma ferramenta paga, mas funcionou quando nenhuma ferramenta gratuita como import.io ou kimono conseguiu renderizar.
Eu amo Python

Respostas:

271

Definitivamente, você desejará começar com uma boa estrutura de web scraping. Mais tarde, você pode decidir que eles são muito limitantes e pode montar sua própria pilha de bibliotecas, mas sem muita experiência em scrape, seu projeto será muito pior do que pjscrape ou scrapy.

Nota: Eu uso os termos rastreamento e raspagem basicamente intercambiáveis ​​aqui. Esta é uma cópia da minha resposta à sua pergunta sobre o Quora, é bem longa.

Ferramentas

Familiarize-se com as ferramentas de desenvolvimento do Firebug ou do Chrome, dependendo do navegador de sua preferência. Isso será absolutamente necessário enquanto você navega no site de onde está obtendo dados e mapeia quais urls contêm os dados que você está procurando e quais formatos de dados constituem as respostas.

Você precisará de um bom conhecimento prático de HTTP e também de HTML e provavelmente desejará encontrar uma pessoa decente no software de proxy intermediário. Você precisará ser capaz de inspecionar solicitações e respostas HTTP e entender como os cookies e as informações da sessão e os parâmetros de consulta estão sendo transmitidos. Fiddler ( http://www.telerik.com/fiddler ) e Charles Proxy ( http://www.charlesproxy.com/ ) são ferramentas populares. Eu uso o mitmproxy ( http://mitmproxy.org/ ) muito, pois sou mais um especialista em teclados do que em mouse.

Algum tipo de ambiente de console / shell / REPL onde você pode experimentar várias partes de código com feedback instantâneo será inestimável. Tarefas de engenharia reversa como essa requerem muitas tentativas e erros, então você desejará um fluxo de trabalho que torne isso fácil.

Língua

O PHP está basicamente fora do ar, não é adequado para esta tarefa e o suporte a biblioteca / framework é pobre nesta área. Python (Scrapy é um ótimo ponto de partida) e Clojure / Clojurescript (incrivelmente poderoso e produtivo, mas uma grande curva de aprendizado) são ótimas linguagens para esse problema. Uma vez que você prefere não aprender um novo idioma e já conhece Javascript, eu definitivamente sugiro usar JS. Eu não usei o pjscrape, mas parece muito bom em uma leitura rápida de seus documentos. É bem adequado e implementa uma excelente solução para o problema que descrevo abaixo.

Uma nota sobre expressões regulares: NÃO USE EXPRESSÕES REGULARES PARA PARSE HTML. Muitos iniciantes fazem isso porque já estão familiarizados com regexes. É um grande erro, usar seletores xpath ou css para navegar html e usar apenas expressões regulares para extrair dados do texto real dentro de um nó html. Isso já pode ser óbvio para você, torna-se óbvio rapidamente se você tentar, mas muitas pessoas perdem muito tempo seguindo por esse caminho por algum motivo. Não tenha medo de seletores xpath ou css, eles são MUITO mais fáceis de aprender do que regexes e foram projetados para resolver esse problema exato.

Sites com muito Javascript

Antigamente, você só precisava fazer uma solicitação http e analisar a resposta HTML. Agora você quase certamente terá que lidar com sites que são uma mistura de solicitações / respostas HTTP HTML padrão e chamadas HTTP assíncronas feitas pela parte javascript do site de destino. É aqui que o seu software proxy e a guia de rede do firebug / devtools se tornam muito úteis. As respostas podem ser html ou json; em casos raros, serão xml ou outra coisa.

Existem duas abordagens para esse problema:

A abordagem de baixo nível:

Você pode descobrir quais urls ajax o javascript do site está chamando e como essas respostas se parecem e fazer essas mesmas solicitações você mesmo. Portanto, você pode obter o html de http://example.com/foobar e extrair um dado e, em seguida, obter a resposta json de http://example.com/api/baz?foo=b ... para obter a outra parte dos dados. Você precisa estar ciente de como passar os cookies ou parâmetros de sessão corretos. É muito raro, mas ocasionalmente alguns parâmetros necessários para uma chamada ajax serão o resultado de algum cálculo maluco feito no javascript do site, a engenharia reversa pode ser irritante.

A abordagem do navegador integrado:

Por que você precisa descobrir quais dados estão em html e quais dados vêm de uma chamada ajax? Gerenciando toda aquela sessão e dados de cookies? Você não precisa fazer isso ao navegar em um site, o navegador e o javascript do site fazem isso. Esse é o ponto principal.

Se você apenas carregar a página em um mecanismo de navegador sem cabeçalho como o phantomjs, ele carregará a página, executará o javascript e informará quando todas as chamadas ajax foram concluídas. Você pode injetar seu próprio javascript se necessário para acionar os cliques apropriados ou o que for necessário para acionar o javascript do site para carregar os dados apropriados.

Agora você tem duas opções, fazer com que ele cuspa o html acabado e analise-o ou injete algum javascript na página que faz a sua análise e formatação de dados e cospe os dados (provavelmente no formato json). Você também pode misturar livremente essas duas opções.

Qual abordagem é a melhor?

Depende, você precisará estar familiarizado e confortável com a abordagem de baixo nível, com certeza. A abordagem de navegador incorporado funciona para qualquer coisa, será muito mais fácil de implementar e fará com que alguns dos problemas mais complicados de raspagem desapareçam. É também uma máquina bastante complexa que você precisa entender. Não se trata apenas de solicitações e respostas HTTP, são solicitações, renderização de navegador integrado, javascript de site, javascript injetado, seu próprio código e interação bidirecional com o processo de navegador integrado.

O navegador integrado também é muito mais lento em escala por causa da sobrecarga de renderização, mas isso quase certamente não fará diferença, a menos que você esteja removendo vários domínios diferentes. Sua necessidade de limitar a taxa de suas solicitações tornará o tempo de renderização completamente insignificante no caso de um único domínio.

Limitação de taxa / comportamento do bot

Você precisa estar muito ciente disso. Você precisa fazer solicitações aos domínios de destino a uma taxa razoável. Você precisa escrever um bot bem comportado ao rastrear sites, e isso significa respeitar o robots.txt e não martelar o servidor com solicitações. Erros ou negligência aqui são muito antiéticos, pois isso pode ser considerado um ataque de negação de serviço. A taxa aceitável varia dependendo de a quem você pergunta, 1req / s é o máximo que o rastreador do Google executa, mas você não é o Google e provavelmente não é tão bem-vindo quanto o Google. Mantenha-o tão lento quanto razoável. Eu sugeriria de 2 a 5 segundos entre cada solicitação de página.

Identifique suas solicitações com uma string de agente de usuário que identifica seu bot e tenha uma página da web para seu bot explicando sua finalidade. Este url vai na string do agente.

Será fácil bloquear se o site quiser bloquear você. Um engenheiro inteligente pode facilmente identificar os bots e alguns minutos de trabalho podem causar semanas de trabalho alterando seu código de raspagem ou simplesmente tornando isso impossível. Se o relacionamento for antagônico, um engenheiro inteligente no local de destino pode impedir completamente um engenheiro gênio de escrever um rastreador. O código de raspagem é inerentemente frágil e pode ser facilmente explorado. Algo que provocaria essa resposta é quase certamente antiético de qualquer maneira, então escreva um bot bem comportado e não se preocupe com isso.

Testando

Não é uma pessoa de teste de unidade / integração? Que pena. Você agora terá que se tornar um. Os sites mudam com freqüência e você mudará seu código com freqüência. Essa é uma grande parte do desafio.

Há muitas partes móveis envolvidas na remoção de um site moderno, boas práticas de teste ajudarão muito. Muitos dos bugs que você encontrará ao escrever este tipo de código serão do tipo que apenas retorna dados corrompidos silenciosamente. Sem bons testes para verificar as regressões, você descobrirá que está salvando dados corrompidos inúteis em seu banco de dados por um tempo sem perceber. Este projeto o deixará muito familiarizado com a validação de dados (encontre algumas boas bibliotecas para usar) e testes. Não há muitos outros problemas que combinam exigir testes abrangentes e serem muito difíceis de testar.

A segunda parte de seus testes envolve armazenamento em cache e detecção de alterações. Enquanto escreve seu código, você não quer martelar o servidor para a mesma página repetidamente sem motivo. Ao executar seus testes de unidade, você deseja saber se seus testes estão falhando porque você quebrou seu código ou porque o site foi reprojetado. Execute seus testes de unidade em uma cópia em cache dos urls envolvidos. Um proxy de cache é muito útil aqui, mas difícil de configurar e usar corretamente.

Você também quer saber se o site mudou. Se eles redesenharem o site e seu rastreador estiver quebrado, seus testes de unidade ainda serão aprovados porque estão sendo executados em uma cópia em cache! Você precisará de outro conjunto menor de testes de integração que não são executados com frequência no site ativo ou de um bom registro e detecção de erros em seu código de rastreamento que registra os problemas exatos, alerta sobre o problema e interrompe o rastreamento. Agora você pode atualizar seu cache, executar seus testes de unidade e ver o que você precisa mudar.

Questões legais

A lei aqui pode ser ligeiramente perigosa se você fizer coisas estúpidas. Se a lei se envolver, você está lidando com pessoas que regularmente se referem ao wget e ao curl como "ferramentas de hacking". Você não quer isso.

A realidade ética da situação é que não há diferença entre usar um software de navegador para solicitar uma url e examinar alguns dados e usar seu próprio software para solicitar uma url e examinar alguns dados. O Google é a maior empresa de scraping do mundo e eles são amados por isso. Identificar o nome do seu bot no agente do usuário e ser aberto sobre os objetivos e intenções do seu rastreador da web ajudará aqui, já que a lei entende o que o Google é. Se você estiver fazendo algo obscuro, como criar contas de usuário falsas ou acessar áreas do site que não deveria (seja "bloqueado" por robots.txt ou por algum tipo de exploração de autorização), esteja ciente de que está fazendo algo antiético e a ignorância da tecnologia por lei será extraordinariamente perigosa aqui. É uma situação ridícula, mas real.

É literalmente possível tentar construir um novo mecanismo de busca cada vez mais como um cidadão íntegro, cometer um erro ou ter um bug em seu software e ser visto como um hacker. Não é algo que você queira, considerando a realidade política atual.

Quem sou eu para escrever essa parede gigante de texto?

Eu escrevi muitos códigos relacionados ao rastreamento da web na minha vida. Tenho feito desenvolvimento de software relacionado à web há mais de uma década como consultor, funcionário e fundador de startups. Os primeiros dias estavam escrevendo crawlers / scrapers perl e sites php. Quando estávamos incorporando iframes ocultos que carregavam dados csv em páginas da web para fazer ajax, antes que Jesse James Garrett o chamasse de ajax, antes que XMLHTTPRequest fosse uma ideia. Antes do jQuery, antes do json. Estou na casa dos 30 anos, o que é aparentemente considerado antigo para este negócio.

Eu escrevi sistemas de rastreamento / raspagem em grande escala duas vezes, uma para uma grande equipe em uma empresa de mídia (em Perl) e recentemente para uma pequena equipe como CTO de uma inicialização de mecanismo de pesquisa (em Python / Javascript). Atualmente trabalho como consultor, principalmente codificando em Clojure / Clojurescript (uma linguagem de especialista maravilhosa em geral e tem bibliotecas que tornam os problemas de rastreador / raspador uma delícia)

Também escrevi sistemas de software anti-rastreamento de sucesso. É extremamente fácil escrever sites quase impossíveis de serem quebrados se você quiser ou para identificar e sabotar bots que você não gosta.

Gosto de escrever crawlers, scrapers e parsers mais do que qualquer outro tipo de software. É desafiador, divertido e pode ser usado para criar coisas incríveis.

Jesse Sherlock
fonte
4
Eu costumava concordar com você sobre o PHP ser uma escolha ruim, mas com as bibliotecas certas não é tão ruim. A manipulação de regex e array / sting é desajeitada, mas pelo lado positivo é rápida e em qualquer lugar.
pguardiario
3
Em um ambiente onde existem algumas bibliotecas que tornam isso um prazer e muitas que o tornam bastante simples e fácil ... por que você se contentaria com "não é tão ruim". Eu concordo, é viável em PHP (e FORTRAN, C, VB, etc.), mas a menos que seu problema seja realmente muito simples, seria uma ideia muito melhor usar as ferramentas certas para o trabalho. E, novamente, a menos que você tenha um problema incrivelmente simples para resolver ... o que importa se o regex está em toda parte? Instalar bibliotecas é muito mais simples do que quase todos os problemas de extração. E, na verdade, o regex costuma ser muito lento para esse problema.
Jesse Sherlock,
5
Você pode estar certo, mas eu sei que não consigo fazer isso tão facilmente em PHP. Antes de deixar o PHP, eu tinha quase uma década de experiência profissional em PHP. Passei mais de um ano em tempo integral construindo um sistema de scraping em escala, em Python, e não consigo imaginar ficar sem algumas das boas bibliotecas que não estão disponíveis em PHP ou sem as técnicas concisas de meta-programação disponíveis em Python . Essa também é a razão pela qual mudei para o Clojure, para obter habilidades de metaprogramação ainda mais poderosas.
Jesse Sherlock de
4
Enlive, junto com o poder do próprio Clojure para códigos específicos de projeto, são os maiores vencedores. Schema é uma ótima biblioteca de validação, que é uma grande parte do código de extração de informações. Atualmente, estou muito feliz com a fácil interoperabilidade com o mundo Java para coisas como Mahout, bem como Nashorn / Rhino para alguns tipos de execução de js. E o pessoal do Clojure é o tipo que escreve bibliotecas como github.com/shriphani/subotai para que você não precise fazer isso. ... continuou no próximo comentário ...
Jesse Sherlock
3
Eu também descobri que quando você realmente precisa de um navegador real e precisa ir com phantomjs / casperjs é realmente ótimo usar clojurescript (geralmente código compartilhado entre clj e cljs usando cljx) para escrever o js que você injeta na página em vez de clojurescript . Core.async é ótimo para coordenar código de rastreamento altamente simultâneo no servidor, bem como sair do inferno de callback dentro do ambiente js (coordenar a automação do navegador com código cljs core.async dentro do phantomjs é o paraíso em comparação com as alternativas).
Jesse Sherlock
21

Sim, você pode fazer isso sozinho. É apenas uma questão de pegar as fontes da página e analisá-las da maneira que você quiser.

Existem várias possibilidades. Uma boa combinação é usar python-requests (construído sobre urllib2, está urllib.requestem Python3) e BeautifulSoup4 , que tem seus métodos para selecionar elementos e também permite seletores CSS :

import requests
from BeautifulSoup4 import BeautifulSoup as bs
request = requests.get("http://foo.bar")
soup = bs(request.text) 
some_elements = soup.find_all("div", class_="myCssClass")

Alguns preferem análise xpath ou pyquery semelhante ao jquery, lxml ou qualquer outra coisa .

Quando os dados que você deseja são produzidos por algum JavaScript , o procedimento acima não funciona. Você precisa de python-ghost ou Selenium. Prefiro este último combinado com o PhantomJS , muito mais leve e simples de instalar e fácil de usar:

from selenium import webdriver
client = webdriver.PhantomJS()
client.get("http://foo")
soup = bs(client.page_source)

Eu aconselharia começar sua própria solução. Você entenderá os benefícios do Scrapy ao fazer isso.

ps: dê uma olhada no scrapely: https://github.com/scrapy/scrapely

pps: dê uma olhada em Portia, para começar a extrair informações visualmente, sem conhecimento de programação: https://github.com/scrapinghub/portia

Ehvince
fonte
Tudo bem, obrigado pela resposta, o único problema é que Python não está no meu conjunto de habilidades. Existem outras linguagens de programação boas que podem fazer as mesmas tarefas? Trabalho principalmente com PHP e Javascript.
0x1ad2
Desculpe a confusão (mencionei a estrutura Python na minha pergunta), mas se Python for a melhor maneira de fazer isso, eu poderia aprender.
0x1ad2
Python torna a eliminação muito fácil. Também é fácil de aprender. O melhor raspador que tem um bom desempenho no momento é o raspador. Eles também têm uma documentação muito boa.
Abhishek