Prosty scraping za pomocą Requests i BeautifulSoup4

Andrzej Galiński · 2021-02-08

Cel: Napisać prosty scraper, potrafiący pobrać stronę i przeanalizować jej zawartość.

Rozwiązanie

Strona (serwowana lokalnie, python3 -m http.server 8123):

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <p>para1</p>
    <p class="c1">para2</p>
    <ul id="lst">
      <li><a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/">BeautifulSoup docs</a></li>
      <li><a href="https://2.python-requests.org/en/master/">Requests docs</a></li>
    </ul>
    <img src="some_image.png" alt="red square">
  </body>
</html>

Scraper:

#!/usr/bin/env python
import requests
import bs4

response = requests.get('http://localhost:8123/sample.html')
assert response.status_code == 200   # nie zaszkodzi sprawdzić, czy się udało

root = bs4.BeautifulSoup(response.text, 'html.parser')

print("Prosty select zwraca wszystkie pasujące elementy:\n", root.select('p'))
print("select_one wybiera pierwszy:\n", root.select_one('p'))
print(".text zwraca zawartość tekstową:\n", root.select_one('p').text)
lst=root.select_one('#lst')
print("Można pobierać obiekty 'ze strukturą':\n", lst)
print("...i odpytywać dalej:\n", lst.select('li a'))
print("Atrybuty są w słowniku attrs:\n", lst.select_one('a').attrs)
print("Można też znajdować elementy po atrybutach:\n", root.select_one('[alt="red square"]'))

Wyniki:

./scrape.py
Prosty select zwraca wszystkie pasujące elementy:
 [<p>para1</p>, <p class="c1">para2</p>]
select_one wybiera pierwszy:
 <p>para1</p>
.text zwraca zawartość tekstową:
 para1
Można pobierać obiekty 'ze strukturą':
 <ul id="lst">
<li><a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/">BeautifulSoup docs</a></li>
<li><a href="https://2.python-requests.org/en/master/">Requests docs</a></li>
</ul>
...i odpytywać dalej:
 [<a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/">BeautifulSoup docs</a>, <a href="https://2.python-requests.org/en/master/">Requests docs</a>]
Atrybuty są w słowniku attrs:
 {'href': 'https://www.crummy.com/software/BeautifulSoup/bs4/doc/'}
Można też znajdować elementy po atrybutach:
 <img alt="red square" src="some_image.png"/>

Uwagi

  • select wystarcza do zdecydowanej większości prostych zastosowań
  • Przeglądanie struktury strony w przeglądarce za pomocą narzędzi do inspekcji jest Dobrym Pomysłem.
  • Eksperymentowanie w IPythonie jest Dobrym Pomysłem i zazwyczaj Koniecznością
  • Zapisywanie stron przed ich sparsowaniem może być Dobrym Pomysłem, przynajmniej w fazie eksperymentowania
  • Wyniki pośrednie można piklować
  • przy scrapowaniu większej liczby stron warto dodać sleep - systemowy, jeśli skrypt jest uruchamiany w pętli w shellu, albo time.sleep w pythonie.

Linki