Raspagem da Web com Python [fechado]

183

Gostaria de pegar os horários diários do nascer e do pôr do sol em um site. É possível copiar conteúdo da Web com Python? quais são os módulos usados? Existe algum tutorial disponível?

eozzy
fonte
3
Python tem várias opções para raspagem na web. Enumerei algumas das opções aqui em resposta a uma pergunta semelhante.
Filippo
Por que não usar o Analisador HTML incorporado na Biblioteca Padrão do Python? Certamente, para uma tarefa tão simples e pouco frequente (apenas uma vez por dia), vejo poucas razões para procurar outras ferramentas. docs.python.org/2.7/library/htmlparser.html
ArtOfWarfare
Espero que este post seja útil para alguém sobre isso. Um bom tutorial para iniciantes. samranga.blogspot.com/2015/08/web-scraping-beginner-python.html Ele usa uma bela biblioteca python de sopa para raspagem na web com python.
Samitha Chathuranga

Respostas:

187

Use urllib2 em combinação com a brilhante biblioteca BeautifulSoup :

import urllib2
from BeautifulSoup import BeautifulSoup
# or if you're using BeautifulSoup4:
# from bs4 import BeautifulSoup

soup = BeautifulSoup(urllib2.urlopen('http://example.com').read())

for row in soup('table', {'class': 'spad'})[0].tbody('tr'):
    tds = row('td')
    print tds[0].string, tds[1].string
    # will print date and sunrise
lesmana
fonte
7
Pequeno comentário: isso pode ser um pouco simplificado usando o pacote de solicitações, substituindo a linha 6 por: soup = BeautifulSoup (orders.get (' example.com'). Texto ) '
D Coetzee
4
Obrigado pela dica. o pacote pedido ainda não existia, quando escrevi o trecho acima ;-)
1
@DerrickCoetzee - sua simplificação gera um erro de MissingSchema (pelo menos na minha instalação). Isso funciona:soup = BeautifulSoup(requests.get('http://example.com').text)
kmote 30/11/2012
@kmote: foi o que eu digitei, mas esqueci backtickso código e o converti em um link. Obrigado!
D # Coetzee
Como você tem certeza de que o conteúdo estará em td e tr. Pode ser em ul e li também certo?
Shashank Hegde
62

Eu realmente recomendo Scrapy.

Cite uma resposta excluída:

  • O rastreamento fragmentado é mais rápido que a mecanização, porque usa operações assíncronas (além do Twisted).
  • O Scrapy tem suporte melhor e mais rápido para analisar (x) html em cima do libxml2.
  • Scrapy é uma estrutura madura com unicode completo, lida com redirecionamentos, respostas compactadas com gzip, codificações ímpares, cache http integrado, etc.
  • Quando você estiver no Scrapy, poderá escrever uma aranha em menos de 5 minutos para baixar imagens, criar miniaturas e exportar os dados extraídos diretamente para csv ou json.
Sjaak Trekhaak
fonte
13
Eu não percebi que essa pergunta já tinha 2 anos de idade, ainda sinto que Scrapy deve ser nomeado aqui caso outra pessoa esteja tendo a mesma pergunta.
Sjaak Trekhaak
4
Scrapy é uma estrutura e, portanto, é horrível e acha que é mais importante que o seu projeto. É uma estrutura por causa das horríveis (desnecessárias) limitações do Twisted.
user1244215
4
@ user1244215: É uma estrutura porque as estruturas são boas. Se você não quiser usá-lo como uma estrutura, não há nada que o impeça de bloquear todo o seu código em um arquivo.
Blender
1
Mas ele não suporta o Python 3.x.
17

Reuni scripts do meu trabalho de raspagem da Web nessa biblioteca de balde de bits .

Exemplo de script para o seu caso:

from webscraping import download, xpath
D = download.Download()

html = D.get('http://example.com')
for row in xpath.search(html, '//table[@class="spad"]/tbody/tr'):
    cols = xpath.search(row, '/td')
    print 'Sunrise: %s, Sunset: %s' % (cols[1], cols[2])

Resultado:

Sunrise: 08:39, Sunset: 16:08
Sunrise: 08:39, Sunset: 16:09
Sunrise: 08:39, Sunset: 16:10
Sunrise: 08:40, Sunset: 16:10
Sunrise: 08:40, Sunset: 16:11
Sunrise: 08:40, Sunset: 16:12
Sunrise: 08:40, Sunset: 16:13
hoju
fonte
10

Eu sugiro fortemente verificar pyquery . Ele usa sintaxe semelhante a jquery (também conhecida como css), o que facilita muito as coisas para quem vem desse contexto.

Para o seu caso, seria algo como:

from pyquery import *

html = PyQuery(url='http://www.example.com/')
trs = html('table.spad tbody tr')

for tr in trs:
  tds = tr.getchildren()
  print tds[1].text, tds[2].text

Resultado:

5:16 AM 9:28 PM
5:15 AM 9:30 PM
5:13 AM 9:31 PM
5:12 AM 9:33 PM
5:11 AM 9:34 PM
5:10 AM 9:35 PM
5:09 AM 9:37 PM
scottmrogowski
fonte
7

Você pode usar urllib2 para fazer solicitações HTTP e, em seguida, terá conteúdo da web.

Você pode obtê-lo assim:

import urllib2
response = urllib2.urlopen('http://example.com')
html = response.read()

Sopa bonita é um analisador de HTML python que deve ser bom para raspagem de tela.

Em particular, aqui está o tutorial deles sobre como analisar um documento HTML.

Boa sorte!

danben
fonte
Pode ser uma ideia definir um máximo nos bytes lidos. response.read (100000000) ou algo assim, para que esses URLs para ISO não preencham sua RAM. Feliz mineração.
21815
4

Eu uso uma combinação de Scrapemark (localizando urls - py2) e httlib2 (baixar imagens - py2 + 3). O scrapemark.py possui 500 linhas de código, mas usa expressões regulares, portanto, pode não ser tão rápido, não testou.

Exemplo para raspar o seu site:

import sys
from pprint import pprint
from scrapemark import scrape

pprint(scrape("""
    <table class="spad">
        <tbody>
            {*
                <tr>
                    <td>{{[].day}}</td>
                    <td>{{[].sunrise}}</td>
                    <td>{{[].sunset}}</td>
                    {# ... #}
                </tr>
            *}
        </tbody>
    </table>
""", url=sys.argv[1] ))

Uso:

python2 sunscraper.py http://www.example.com/

Resultado:

[{'day': u'1. Dez 2012', 'sunrise': u'08:18', 'sunset': u'16:10'},
 {'day': u'2. Dez 2012', 'sunrise': u'08:19', 'sunset': u'16:10'},
 {'day': u'3. Dez 2012', 'sunrise': u'08:21', 'sunset': u'16:09'},
 {'day': u'4. Dez 2012', 'sunrise': u'08:22', 'sunset': u'16:09'},
 {'day': u'5. Dez 2012', 'sunrise': u'08:23', 'sunset': u'16:08'},
 {'day': u'6. Dez 2012', 'sunrise': u'08:25', 'sunset': u'16:08'},
 {'day': u'7. Dez 2012', 'sunrise': u'08:26', 'sunset': u'16:07'}]
Nils Lindemann
fonte
1

Facilite sua vida usando CSS Selectors

Sei que cheguei atrasado para a festa, mas tenho uma boa sugestão para você.

O uso BeautifulSoupjá foi sugerido. Prefiro usar CSS Selectorspara extrair dados dentro do HTML

import urllib2
from bs4 import BeautifulSoup

main_url = "http://www.example.com"

main_page_html  = tryAgain(main_url)
main_page_soup = BeautifulSoup(main_page_html)

# Scrape all TDs from TRs inside Table
for tr in main_page_soup.select("table.class_of_table"):
   for td in tr.select("td#id"):
       print(td.text)
       # For acnhors inside TD
       print(td.select("a")[0].text)
       # Value of Href attribute
       print(td.select("a")[0]["href"])

# This is method that scrape URL and if it doesnt get scraped, waits for 20 seconds and then tries again. (I use it because my internet connection sometimes get disconnects)
def tryAgain(passed_url):
    try:
        page  = requests.get(passed_url,headers = random.choice(header), timeout = timeout_time).text
        return page
    except Exception:
        while 1:
            print("Trying again the URL:")
            print(passed_url)
            try:
                page  = requests.get(passed_url,headers = random.choice(header), timeout = timeout_time).text
                print("-------------------------------------")
                print("---- URL was successfully scraped ---")
                print("-------------------------------------")
                return page
            except Exception:
                time.sleep(20)
                continue 
Umair
fonte
1

Se pensarmos em obter o nome dos itens de qualquer categoria específica, podemos fazer isso especificando o nome da classe dessa categoria usando o seletor css:

import requests ; from bs4 import BeautifulSoup

soup = BeautifulSoup(requests.get('https://www.flipkart.com/').text, "lxml")
for link in soup.select('div._2kSfQ4'):
    print(link.text)

Estes são os resultados parciais da pesquisa:

Puma, USPA, Adidas & moreUp to 70% OffMen's Shoes
Shirts, T-Shirts...Under ₹599For Men
Nike, UCB, Adidas & moreUnder ₹999Men's Sandals, Slippers
Philips & moreStarting 99LED Bulbs & Emergency Lights
SIM
fonte
0

Aqui está um rastreador da web simples, usei o BeautifulSoup e procuraremos todos os links (âncoras) cujo nome da classe é _3NFO0d. Eu usei Flipkar.com, é uma loja de varejo online.

import requests
from bs4 import BeautifulSoup
def crawl_flipkart():
    url = 'https://www.flipkart.com/'
    source_code = requests.get(url)
    plain_text = source_code.text
    soup = BeautifulSoup(plain_text, "lxml")
    for link in soup.findAll('a', {'class': '_3NFO0d'}):
        href = link.get('href')
        print(href)

crawl_flipkart()
Atul Chavan
fonte
0

Python tem boas opções para raspar a web. O melhor com uma estrutura é arranhado . Pode ser um pouco complicado para iniciantes, então aqui está uma pequena ajuda.
1. Instale o python acima de 3,5 (os mais baixos até 2,7 funcionarão).
2. Crie um ambiente no conda (eu fiz isso).
3. Instale o scrapy em um local e execute a partir daí.
4. Scrapy shellfornecerá uma interface interativa para testar seu código.
5. Scrapy startproject projectnamecriará uma estrutura.
6. Scrapy genspider spidernamecriará uma aranha. Você pode criar quantas aranhas quiser. Enquanto isso, verifique se você está dentro do diretório do projeto.


O mais fácil é usar solicitações e uma bela sopa . Antes de começar, dê uma hora para examinar a documentação, a maioria das dúvidas será resolvida. O BS4 oferece uma ampla variedade de analisadores que você pode optar. Use user-agente sleeppara facilitar a raspagem. BS4 retorna um bs.tag, então usevariable[0] . Se houver js em execução, você não poderá raspar usando solicitações e bs4 diretamente. Você pode obter o link da API e analisar o JSON para obter as informações necessárias ou tentar selenium.

Chris D'mello
fonte