Cara menggunakan python web scraping

oleh Colin OKeefe23 Jan 2018, diterjemahkan langsung dari realpython.com

Cara menggunakan python web scraping

Dasar-dasar Scraping Web

Apa itu web scraping? Pertimbangkan skenario berikut ini:

Bayangkan suatu hari, tiba-tiba, Anda mendapati diri berpikir “Wah, saya bertanya-tanya, siapa lima matematikawan terpopuler?”

Anda sedikit berpikir, dan mendapatkan ide untuk menggunakan XTools Wikipedia untuk mengukur popularitas seorang matematikawan dengan menyamakan popularitas dengan tampilan halaman. Misalnya, lihatlah halaman Henri Poincaré . Di sana Anda dapat melihat bahwa tampilan halaman Poincaré selama 60 hari terakhir adalah, mulai Desember 2017, sekitar 32.000.

Selanjutnya, Anda googling untuk “matematikawan terkenal” dan temukan sumber ini yang mencantumkan 100 nama. Sekarang Anda memiliki kedua halaman daftar nama matematikawan dan memiliki situs web yang memberikan informasi tentang bagaimana “populer” matematikawan itu. Sekarang apa?

Di sinilah Python dan web scraping masuk. Web scraping adalah tentang mendownload data terstruktur dari web, memilih beberapa data itu, dan meneruskan semua yang Anda pilih ke proses lain.

Dalam tutorial ini, Anda akan menulis program Python yang mendownload daftar 100 matematikawan dan halaman XTools mereka, memilih data tentang popularitas mereka, dan selesai dengan memberi tahu kami semua tentang top 10 matematikawan paling populer! Mari kita mulai.

Menyiapkan Scraper Python Web

Anda akan menggunakan lingkungan virtual Python 3 dan Python sepanjang tutorial. Jangan ragu untuk mengatur semuanya sesuka Anda, tapi inilah cara saya melakukannya:

$ python3 -m venv venv
$ . ./venv/bin/activate

Anda hanya perlu menginstal dua paket berikut:

  • requests untuk melakukan permintaan HTTP.
  • BeautifulSoup4 untuk menangani semua pemrosesan HTML Anda.

Mari instal dependensi ini dengan pip:

$ pip install requests BeautifulSoup4

Akhirnya, jika Anda mengikuti, jalankan editor teks favorit Anda dan buatlah sebuah file bernama mathematicians.py. Mulailah dengan memasukkan import di atas:

from requests import get
from requests.exceptions import RequestException
from contextlib import closing
from bs4 import BeautifulSoup

Membuat Permintaan Web

Tugas pertama Anda adalah mendownload halaman web. Paket Requests datang untuk menyelamatkan. requestsbertujuan untuk menjadi alat yang mudah digunakan untuk melakukan semua hal HTTP dengan Python, dan itu tidak mengecewakan. Dalam tutorial ini, Anda hanya memerlukan fungsi requests.get, tapi Anda pasti harus checkout dokumentasi lengkap saat Anda ingin melangkah lebih jauh.

Fungsi pertama anda:

def simple_get(url):
"""
Attempts to get the content at `url` by making an HTTP GET request.
If the content-type of response is some kind of HTML/XML, return the
text content, otherwise return None
"""
try:
with closing(get(url, stream=True)) as resp:
if is_good_response(resp):
return resp.content
else:
return None
except RequestException as e:
log_error('Error during requests to {0} : {1}'.format(url, str(e)))
return None
def is_good_response(resp):
"""
Returns true if the response seems to be HTML, false otherwise
"""
content_type = resp.headers['Content-Type'].lower()
return (resp.status_code == 200
and content_type is not None
and content_type.find('html') > -1)
def log_error(e):
"""
It is always a good idea to log errors.
This function just prints them, but you can
make it do anything.
"""
print(e)

Fungsi simple_get menerima satu url argumen. Ini kemudian membuat GET permintaan untuk url itu. Jika tidak ada yang salah, Anda akan mendapatkan konten HTML mentah untuk laman yang Anda minta. Jika ada masalah dengan permintaan Anda (seperti url buruk atau server rusak), function Anda kembali None.

Anda mungkin telah memperhatikan penggunaan closing fungsi dalam definisi simple_get. Fungsi closing memastikan bahwa setiap sumber daya jaringan dibebaskan ketika mereka pergi keluar dari ruang lingkup dalam with blok. Menggunakan closing seperti itu adalah praktik yang baik dan membantu mencegah kesalahan fatal dan batas waktu jaringan.

Anda bisa menguji simple_get seperti ini:

>>> from mathematicians import simple_get
>>> raw_html = simple_get('https://realpython.com/blog/')
>>> len(raw_html)
33878
>>> no_html = simple_get('https://realpython.com/blog/nope-not-gonna-find-it')
>>> no_html is None
True

Wrangling HTML Dengan BeautifulSoup

Setelah Anda memiliki HTML mentah di depan Anda, Anda dapat mulai memilih dan mengekstraknya. Untuk tujuan ini anda akan menggunakan BeautifulSoup. Konstruktor BeautifulSoup mem-parsing string HTML baku dan menghasilkan sebuah objek yang mencerminkan struktur dokumen HTML. Objek mencakup banyak metode untuk memilih, melihat, dan memanipulasi nodus DOM dan konten teks.

Sebagai contoh, perhatikan dokumen HTML berikut ini:

<!DOCTYPE html>
<html>
<head>
<title>Contrived Example</title>
</head>
<body>
<p id="eggman"> I am the egg man </p>
<p id="walrus"> I am the walrus </p>
</body>
</html>

Misalkan HTML di atas tersimpan dalam file contrived.html, maka anda bisa menggunakan BeautifulSoup seperti ini:

>>> from bs4 import BeautifulSoup
>>> raw_html = open('contrived.html').read()
>>> html = BeautifulSoup(raw_html, 'html.parser')
>>> for p in html.select('p'):
... if p['id'] == 'walrus':
... print(p.text)
'I am the walrus'

Melanggar contoh, Anda pertama-tama mengurai HTML mentah dengan mengirimkannya ke konstruktor BeautifulSoup. BeautifulSoup menerima beberapa backend parser tapi backend standar adalah 'html.parser', yang Anda berikan di sini sebagai argumen kedua. (Jika Anda lupa memberi 'html.parser' kode itu masih akan berfungsi, namun Anda akan melihat cetakan peringatan ke layar Anda.)

Metode select pada html objek memungkinkan Anda menggunakan CSS untuk mencari unsur-unsur dalam dokumen. Dalam kasus di atas, html.select('p') kembalikan daftar elemen paragraf. Masing-masing p memiliki atribut HTML yang dapat Anda akses seperti dict. Sebagai gantinya if p['id'] == 'walrus', misalnya, Anda memeriksa apakah id atributnya sama dengan string 'walrus', yang sesuai dengan <p id="walrus"> HTML.

Menggunakan BeautifulSoup untuk Mendapatkan Nama Matematika

Sekarang bahwa Anda telah memberikan BeautifulSoup's select metode pendek test drive, bagaimana Anda mencari tahu apa untuk memasok ke select? Cara tercepat adalah keluar dari Python dan masuk ke alat pengembang peramban web Anda. Anda dapat menggunakan browser Anda untuk memeriksa dokumen dalam beberapa detail - Saya biasanya mencari id atau class atribut elemen atau informasi lainnya yang secara unik mengidentifikasi informasi yang ingin saya ekstrak.

Untuk membuat masalah menjadi konkret, beralihlah ke daftar matematikawan yang Anda lihat sebelumnya. Menghabiskan satu atau dua menit untuk melihat sumber halaman ini, Anda dapat melihat bahwa setiap nama matematikawan muncul di dalam konten teks sebuah tag <li>. Bahkan lebih baik lagi, <li>tag pada halaman ini sepertinya tidak berisi apa-apa selain nama matematikawan.

Berikut adalah tampilan singkat menggunakan Python:

>>> raw_html = simple_get('http://www.fabpedigree.com/james/mathmen.htm')
>>> html = BeautifulSoup(raw_html, 'html.parser')
>>> for i, li in enumerate(html.select('li')):
print(i, li.text)
0 Isaac Newton
Archimedes
Carl F. Gauss
Leonhard Euler
Bernhard Riemann
1 Archimedes
Carl F. Gauss
Leonhard Euler
Bernhard Riemann
2 Carl F. Gauss
Leonhard Euler
Bernhard Riemann
3 Leonhard Euler
Bernhard Riemann
4 Bernhard Riemann# 5 ... and many more...

Percobaan di atas menunjukkan bahwa beberapa elemen <li> mengandung beberapa nama yang dipisahkan oleh karakter baris baru, dan yang lainnya hanya berisi satu nama. Dengan informasi ini, Anda dapat menulis fungsi Anda untuk mengambil satu daftar nama:

def get_names():
"""
Downloads the page where the list of mathematicians is found
and returns a list of strings, one per mathematician
"""
url = 'http://www.fabpedigree.com/james/mathmen.htm'
response = simple_get(url)
if response is not None:
html = BeautifulSoup(response, 'html.parser')
names = set()
for li in html.select('li'):
for name in li.text.split('\n'):
if len(name) > 0:
names.add(name.strip())
return list(names)
# Raise an exception if we failed to get any data from the url
raise Exception('Error retrieving contents at {}'.format(url))

Fungsi get_names mendownload halaman dan iterates atas <li>unsur-unsur, memilih setiap nama yang terjadi. Selanjutnya, Anda menambahkan setiap nama ke Python set, yang memastikan bahwa Anda tidak berakhir dengan nama duplikat. Akhirnya Anda mengubah set ke daftar dan mengembalikannya.

Mendapatkan Skor Popularitas

Bagus, kamu hampir selesai! Setelah Anda memiliki daftar nama, Anda harus memilih tampilan halaman untuk masing-masing daftar. Fungsi yang Anda tulis mirip dengan fungsi yang Anda buat untuk mendapatkan daftar nama, hanya sekarang Anda memberi nama dan memilih nilai integer dari halaman.

Sekali lagi, pertama-tama Anda harus memeriksa halaman contoh di alat pengembang peramban Anda. Sepertinya teks muncul di dalam <a>elemen, dan hrefatribut elemen itu selalu berisi string 'latest-60' sebagai substring. Itu semua informasi yang Anda butuhkan untuk menulis fungsi Anda!

def get_hits_on_name(name):
"""
Accepts a `name` of a mathematician and returns the number
of hits that mathematician's wikipedia page received in the
last 60 days, as an `int`
"""
# url_root is a template string that used to buld a URL.
url_root = 'https://xtools.wmflabs.org/articleinfo/en.wikipedia.org/{}'
response = simple_get(url_root.format(name))
if response is not None:
html = BeautifulSoup(response, 'html.parser')
hit_link = [a for a in html.select('a')
if a['href'].find('latest-60') > -1]
if len(hit_link) > 0:
# Strip commas:
link_text = hit_link[0].text.replace(',', '')
try:
# Convert to integer
return int(link_text)
except:
log_error("couldn't parse {} as an `int`".format(link_text))
log_error('No pageviews found for {}'.format(name))
return None

Puting It All Together

Anda telah mencapai titik di mana Anda akhirnya bisa menemukan matematikawan mana yang paling dicintai oleh publik! Rencananya sederhana saja:

  • Dapatkan daftar nama,
  • Iterate di atas daftar untuk mendapatkan “skor popularitas” untuk setiap nama; dan
  • Selesai dengan menyortir nama dengan popularitas.

Sederhana kan? Nah, ada satu hal yang belum disebutkan:errors.

Bekerja dengan data dunia nyata yang berantakan, dan mencoba untuk memaksa data yang berantakan ke dalam bentuk yang seragam akan selalu menghasilkan kesalahan sesekali yang melompat untuk mengacaukan penglihatan bersih Anda yang bagus tentang bagaimana seharusnya hal itu terjadi. Idealnya, Anda ingin melacak kesalahan saat terjadi agar mendapatkan kualitas data Anda yang lebih baik.

Untuk tujuan Anda saat ini, Anda akan melacak contoh saat Anda tidak dapat menemukan skor popularitas untuk nama matematikawan tertentu. Di akhir naskah, Anda akan mencetak pesan yang menunjukkan jumlah matematikawan yang tertinggal dari peringkat.

Inilah kodenya:

if __name__ == '__main__':
print('Getting the list of names....')
names = get_names()
print('... done.\n')
results = [] print('Getting stats for each name....') for name in names:
try:
hits = get_hits_on_name(name)
if hits is None:
hits = -1
results.append((hits, name))
except:
results.append((-1, name))
log_error('error encountered while processing '
'{}, skipping'.format(name))
print('... done.\n') results.sort()
results.reverse()
if len(results) > 5:
top_marks = results[:5]
else:
top_marks = results
print('\nThe most popular mathematicians are:\n')
for (mark, mathematician) in top_marks:
print('{} with {} page views'.format(mathematician, mark))
no_results = len([res for res in results if res[0] == -1])
print('\nBut we did not find results for '
'{} mathematicians on the list'.format(no_results))

Dan itu dia!

Saat menjalankan skrip, Anda harus melihat laporan berikut ini:

The most popular mathematicians are:Albert Einstein with 1089615 page views
Isaac Newton with 581612 page views
Srinivasa Ramanujan with 407141 page views
Aristotle with 399480 page views
Galileo Galilei with 375321 page views
But we did not find results for 19 mathematicians on our list

Kesimpulan & Langkah Selanjutnya

Web scraping adalah bidang yang besar, dan Anda baru saja menyelesaikan tur singkat bidang itu dengan menggunakan Python saat Anda membimbing. Anda bisa mendapatkan cukup jauh menggunakan hanya requests dan BeautifulSoup, tapi seperti yang Anda ikuti bersama, Anda mungkin telah menemukan beberapa pertanyaan:

  • Apa yang terjadi jika konten halaman dimuat sebagai hasil permintaan Javascript asinkron? (Simak API Python Selenium .)
  • Bagaimana cara menulis spider web atau bot mesin pencari yang melintasi sebagian besar web?
  • Apa hal Scrapy ini yang selalu saya dengar?

Source : https://realpython.com/blog/python/python-web-scraping-practical-introduction/

Apa itu scraping python?

Salah satu fungsi library python adalah untuk membantu proses web scraping. Web scraping adalah proses mengumpulkan data terstruktur dari sebuah web secara otomatis. Proses ini juga disebut dengan proses ekstraksi data website.

Apa yang kalian ketahui tentang Web Scraping?

Dilansir dari ParseHub, web scraping adalah suatu cara yang mengacu pada ekstraksi data dari suatu website. Jadi, saat kamu melakukan proses pengambilan data dari website dan menyimpannya dalam Microsoft Excel, Google Sheet, atau aplikasi sejenisnya, maka itulah yang disebut web scraping.