Introdução e Legal
Nesta postagem, mostrarei como criar um rastreador da web em Python. Esta postagem acompanha @scosta / 921e3afc9018 “rel =” nofollow “> esta postagem do blog se você estiver interessado em descobrir por que estou postando isso. Você também deve ler e compreender as leis que envolvem o rastreamento da web e não usar este script fazer qualquer coisa que possa ser considerada ilegal.
Ok, agora que isso foi resolvido, vamos começar!
Etapa 1: A Estrutura
Eu sempre começo meus scripts com uma docstring, a (s) definição (ões) de classe e, em seguida, retiro as funções.
'''
A web crawler for extracting email addresses from web pages.
Takes a string of URLs and requests each page, checks to see if we've
found any emails and prints each email it finds.
'''
class Crawler(object):
def __init__(self, urls):
'''
@urls: a string containing the (comma separated) URLs to crawl.
'''
self.urls = urls.split(',')
def crawl(self):
'''
Iterate the list of URLs and request each page, then parse it and
print the emails we find.
'''
pass
@staticmethod
def request(url):
'''
Request @url and return the page contents.
'''
pass
@staticmethod
def process(data):
'''
Process @data and yield the emails we find in it.
'''
pass
Algumas coisas importantes a serem observadas:
* As funções request
e process
são decoradas usando o @staticmethod
decorador do Python, pois não precisam de acesso a nada que os self
forneça.
* Estamos dividindo as URLs pelas ','
quais passamos para que possamos passar várias da linha de comando.
* Os docstrings de módulo e função são compatíveis com PEP8 .
Passo 2: crawl
CoderWall força a rolagem em blocos de código após um pequeno número de linhas, então vou fazer essa função por função. Posso ter que entrar em seu projeto de montagem e solicitar e talvez construir esse recurso!
Com essa função, vamos apenas passar cada URL para request
e, em seguida, processar os dados com process
.
def crawl(self):
'''
Iterate the list of URLs and request each page, then parse it and print
the emails we find.
'''
for url in self.urls:
data = self.request(url)
for email in self.process(data):
print email
Não é uma forma muito boa imprimir os e-mails dentro desta função – seria melhor devolvê-los (ou cedê-los) main
e então deixar que ele decida o que fazer com eles, mas vamos deixar por enquanto. Talvez eu faça um V2 mais “funcional” desse post mais tarde!
Etapa 3: request
Esta função irá solicitar a página e, em seguida, retornar o corpo da página. Ele usa a biblioteca “urllib2”, então certifique-se de adicioná-la ao início do seu script (dê uma olhada na versão final do script no final deste post para ver o que quero dizer).
@staticmethod
def request(url):
'''
Request @url and return the page contents.
'''
response = urllib2.urlopen(url)
return response.read()
É uma função bastante simples, apenas solicita a página, lê a resposta e a retorna para a crawl
função.
Passo 4: process
Esta função é responsável por pesquisar os dados da página para endereços de e-mail. Ele faz isso usando uma expressão regular (ou regex). Esta é uma implementação super simples que irá perder muitos e-mails (devido ao regex), mas eu queria mantê-la direta para que os leitores que nunca usaram regex possam entender também.
@staticmethod
def process(data):
'''
Process @data and yield the emails we find in it.
'''
for email in re.findall(r'(w+@w+.com)', data):
yield email
Esta função requer a biblioteca “re”, portanto, certifique-se de adicioná-la com “urllib2”.
Etapa 5: main
Eu realmente gosto de usar o “argparse” do Python para meus scripts, independentemente de quão simples eles sejam. Vamos usá-lo aqui para permitir que o usuário insira um e-mail ou e-mails da linha de comando e depois criaremos um novo Crawler
e veremos se podemos encontrar alguns e-mails.
def main():
argparser = argparse.ArgumentParser()
argparser.add_argument(
'--urls', dest='urls', required=True,
help='A comma separated string of emails.')
parsed_args = argparser.parse_args()
crawler = Crawler(parsed_args.urls)
crawler.crawl()
if __name__ == '__main__':
sys.exit(main())
Este novo código requer as bibliotecas “argparse” e “sys”, então certifique-se de adicioná-las com as outras inclusões no topo do seu script!
Empacotando
Ok, aqui está o seu script!
'''
A web crawler for extracting email addresses from web pages.
Takes a string of URLs and requests each page, checks to see if we've
found any emails and prints each email it finds.
'''
import argparse
import re
import sys
import urllib2
class Crawler(object):
def __init__(self, urls):
'''
@urls: a string containing the (comma separated) URLs to crawl.
'''
self.urls = urls.split(',')
def crawl(self):
'''
Iterate the list of URLs and request each page, then parse it and
print the emails we find.
'''
for url in self.urls:
data = self.request(url)
for email in self.process(data):
print email
@staticmethod
def request(url):
'''
Request @url and return the page contents.
'''
response = urllib2.urlopen(url)
return response.read()
@staticmethod
def process(data):
'''
Process @data and yield the emails we find in it.
'''
for email in re.findall(r'(w+@w+.com)', data):
yield email
def main():
argparser = argparse.ArgumentParser()
argparser.add_argument(
'--urls', dest='urls', required=True,
help='A comma separated string of emails.')
parsed_args = argparser.parse_args()
crawler = Crawler(parsed_args.urls)
crawler.crawl()
if __name__ == '__main__':
sys.exit(main())
Aí está! Teste-o na linha de comando usando python crawler.py --urls https://www.example.com/
.
Observe que “http” ou “https” são necessários porque request
falharão sem ele. Vou deixar para você corrigir esse bug!
Deixe-me saber o que você acha e o que gostaria de ver a seguir nos comentários!