Web scraping avec Python [fermé]


183

Je voudrais saisir les heures quotidiennes de lever / coucher du soleil sur un site Web. Est-il possible de récupérer du contenu Web avec Python? quels sont les modules utilisés? Y a-t-il un tutoriel disponible?


3
Python a plusieurs options pour le web scraping. J'ai énuméré certaines des options ici en réponse à une question similaire.
filippo

Pourquoi ne pas simplement utiliser l'analyseur HTML intégré dans la bibliothèque standard Python? Certes, pour une tâche si simple et peu fréquente (juste une fois par jour), je ne vois guère de raison de rechercher d'autres outils. docs.python.org/2.7/library/htmlparser.html
ArtOfWarfare

J'espère que cet article pourra être utile à quelqu'un à ce sujet. Un bon tutoriel pour un débutant. samranga.blogspot.com/2015/08/web-scraping-beginner-python.html Il utilise une belle bibliothèque de soupe python pour le web scraping avec python.
Samitha Chathuranga

Réponses:


187

Utilisez urllib2 en combinaison avec la brillante bibliothèque 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

7
Petit commentaire: cela peut être légèrement simplifié en utilisant le package requests en remplaçant la ligne 6 par: soup = BeautifulSoup (requests.get (' example.com'). Text )
D Coetzee

4
Merci pour le conseil. le package de requête n'existait pas encore, quand j'ai écrit l'extrait ci-dessus ;-)

1
@DerrickCoetzee - votre simplification soulève une erreur MissingSchema (au moins sur mon installation). Cela fonctionne:soup = BeautifulSoup(requests.get('http://example.com').text)
kmote

@kmote: c'est ce que j'ai tapé mais j'ai oublié le backticksautour du code et il l'a converti en lien. Merci!
D Coetzee

Comment êtes-vous sûr que le contenu sera en td et tr. Cela peut être aussi bien dans ul et li?
Shashank Hegde

62

Je recommanderais vraiment Scrapy.

Citation d'une réponse supprimée:

  • L'exploration Scrapy est plus rapide que la mécanisation car elle utilise des opérations asynchrones (en plus de Twisted).
  • Scrapy a un support meilleur et plus rapide pour l'analyse (x) html en plus de libxml2.
  • Scrapy est un framework mature avec unicode complet, gère les redirections, les réponses gzippées, les encodages impairs, le cache http intégré, etc.
  • Une fois que vous êtes dans Scrapy, vous pouvez écrire une araignée en moins de 5 minutes qui télécharge des images, crée des vignettes et exporte les données extraites directement vers csv ou json.

13
Je n'ai pas remarqué que cette question avait déjà 2 ans, je pense toujours que Scrapy devrait être nommé ici au cas où quelqu'un d'autre aurait la même question.
Sjaak Trekhaak

4
Scrapy est un cadre, et donc horrible et pense que c'est plus important que votre projet. C'est un cadre en raison des horribles limitations (inutiles) de Twisted.
user1244215

4
@ user1244215: C'est un framework parce que les frameworks sont sympas. Si vous ne voulez pas l'utiliser comme framework, rien ne vous empêche de brouiller tout votre code dans un seul fichier.
Blender

1
Mais il ne prend pas en charge Python 3.x.

17

J'ai rassemblé les scripts de mon travail de scraping Web dans cette bibliothèque de bits .

Exemple de script pour votre cas:

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])

Production:

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

10

Je suggère fortement de vérifier pyquery . Il utilise une syntaxe de type jquery (alias css) qui rend les choses vraiment faciles pour ceux qui viennent de ce contexte.

Pour votre cas, ce serait quelque chose comme:

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

Production:

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

7

Vous pouvez utiliser urllib2 pour effectuer les requêtes HTTP, puis vous aurez du contenu Web.

Vous pouvez l'obtenir comme ceci:

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

Belle soupe est un analyseur HTML python qui est censé être bon pour le grattage d'écran.

En particulier, voici leur tutoriel sur l'analyse d'un document HTML.

Bonne chance!


Il peut être judicieux de définir un maximum sur les octets lus. response.read (100000000) ou quelque chose pour que ces URL pour les ISO ne remplissent pas votre RAM. Bonne exploitation minière.
andrew pate

4

J'utilise une combinaison de Scrapemark (recherche d'urls - py2) et httlib2 (téléchargement d'images - py2 + 3). Le scrapemark.py a 500 lignes de code, mais utilise des expressions régulières, donc ce n'est peut-être pas si rapide, n'a pas testé.

Exemple de scraping de votre site Web:

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] ))

Usage:

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

Résultat:

[{'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'}]

1

Facilitez-vous la vie en utilisant CSS Selectors

Je sais que je suis arrivé en retard pour faire la fête mais j'ai une bonne suggestion pour vous.

L'utilisation BeautifulSoupest déjà suggérée, je préférerais utiliser CSS Selectorspour récupérer des données dans du 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 

1

Si nous pensons obtenir le nom des éléments d'une catégorie spécifique, nous pouvons le faire en spécifiant le nom de classe de cette catégorie à l'aide du sélecteur 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)

Voici les résultats de la recherche partielle:

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

0

Voici un simple robot d'exploration, j'ai utilisé BeautifulSoup et nous chercherons tous les liens (ancres) dont le nom de classe est _3NFO0d. J'ai utilisé Flipkar.com, c'est un magasin de vente au détail en ligne.

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()

0

Python a de bonnes options pour gratter le Web. Le meilleur avec un cadre est tremblant . Cela peut être un peu délicat pour les débutants, alors voici un peu d'aide.
1. Installez python au-dessus de 3.5 (les inférieurs jusqu'à 2.7 fonctionneront).
2. Créez un environnement dans conda (je l'ai fait).
3. Installez scrapy à un endroit et exécutez à partir de là.
4. Scrapy shellvous donnera une interface interactive pour tester votre code.
5. Scrapy startproject projectnamecréera un cadre.
6. Scrapy genspider spidernamecréera une araignée. Vous pouvez créer autant d'araignées que vous le souhaitez. Tout en faisant cela, assurez-vous que vous êtes dans le répertoire du projet.


Le plus simple est d'utiliser les demandes et la belle soupe . Avant de commencer, donnez une heure pour parcourir la documentation, cela résoudra la plupart de vos doutes. BS4 propose une large gamme d'analyseurs pour lesquels vous pouvez opter. Utilisez user-agentet sleeppour faciliter le grattage. BS4 renvoie un bs.tag donc utilisez variable[0]. Si js est en cours d'exécution, vous ne pourrez pas utiliser directement les requêtes et bs4. Vous pouvez obtenir le lien API, puis analyser le JSON pour obtenir les informations dont vous avez besoin ou essayer selenium.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.