Bagaimana saya bisa mengambil tautan halaman web dan menyalin alamat url tautan menggunakan Python?
141
Bagaimana saya bisa mengambil tautan halaman web dan menyalin alamat url tautan menggunakan Python?
Berikut cuplikan singkat menggunakan kelas SoupStrainer di BeautifulSoup:
import httplib2
from bs4 import BeautifulSoup, SoupStrainer
http = httplib2.Http()
status, response = http.request('http://www.nytimes.com')
for link in BeautifulSoup(response, parse_only=SoupStrainer('a')):
if link.has_attr('href'):
print(link['href'])
Dokumentasi BeautifulSoup sebenarnya cukup bagus, dan mencakup sejumlah skenario khas:
https://www.crummy.com/software/BeautifulSoup/bs4/doc/
Sunting: Perhatikan bahwa saya menggunakan kelas SoupStrainer karena ini sedikit lebih efisien (memori dan kecepatan bijaksana), jika Anda tahu apa yang Anda parsing sebelumnya.
/usr/local/lib/python2.7/site-packages/bs4/__init__.py:128: UserWarning: The "parseOnlyThese" argument to the BeautifulSoup constructor has been renamed to "parse_only."
has_attr
. Sebaliknya saya melihat ada sesuatu yang disebuthas_key
dan berfungsi.Demi kelengkapannya, versi BeautifulSoup 4, menggunakan pengkodean yang disediakan oleh server juga:
atau versi Python 2:
dan versi menggunakan
requests
pustaka , yang seperti yang ditulis akan bekerja di Python 2 dan 3:The
soup.find_all('a', href=True)
panggilan menemukan semua<a>
elemen yang memilikihref
atribut; elemen tanpa atribut dilewati.BeautifulSoup 3 menghentikan pengembangan pada Maret 2012; proyek baru benar-benar harus menggunakan BeautifulSoup 4, selalu.
Perhatikan bahwa Anda harus membiarkan decoding HTML dari byte ke BeautifulSoup . Anda dapat memberi tahu BeautifulSoup tentang karakter yang ditemukan di header respons HTTP untuk membantu dalam decoding, tetapi ini bisa salah dan bertentangan dengan
<meta>
info header yang ditemukan dalam HTML itu sendiri, itulah sebabnya mengapa di atas menggunakan metode kelas internal BeautifulSoupEncodingDetector.find_declared_encoding()
untuk memastikan bahwa petunjuk enkode tertanam seperti itu menang atas server yang tidak terkonfigurasi.Dengan
requests
,response.encoding
atribut default ke Latin-1 jika respons memilikitext/*
mimetype, bahkan jika tidak ada karakter yang dikembalikan. Ini konsisten dengan HTTP RFCs tetapi menyakitkan ketika digunakan dengan parsing HTML, jadi Anda harus mengabaikan atribut itu ketika tidakcharset
diatur dalam header Tipe-Konten.sumber
SoupStrainer
maksud Anda? Itu tidak pergi ke mana pun, itu masih bagian dari proyek .Orang lain merekomendasikan BeautifulSoup, tetapi jauh lebih baik menggunakan lxml . Meskipun namanya, itu juga untuk parsing dan memo HTML. Ini jauh, jauh lebih cepat daripada BeautifulSoup, dan bahkan menangani "rusak" HTML lebih baik daripada BeautifulSoup (klaim mereka untuk ketenaran). Ini memiliki API kompatibilitas untuk BeautifulSoup juga jika Anda tidak ingin mempelajari API lxml.
Ian Blicking setuju .
Tidak ada alasan untuk menggunakan BeautifulSoup lagi, kecuali Anda berada di Google App Engine atau sesuatu di mana segala sesuatu yang tidak murni Python tidak diizinkan.
lxml.html juga mendukung pemilih CSS3 sehingga hal semacam ini sepele.
Contoh dengan lxml dan xpath akan terlihat seperti ini:
sumber
lxml
sebagai parser default jika diinstal.sumber
Kode berikut adalah untuk mengambil semua tautan yang tersedia di halaman web menggunakan
urllib2
danBeautifulSoup4
:sumber
Di bawah tenda BeautifulSoup sekarang menggunakan lxml. Permintaan, lxml, & daftar pemahaman menjadikan kombo pembunuh.
Dalam daftar comp, "jika '//' dan 'url.com' tidak dalam x" adalah metode sederhana untuk menggosok daftar url dari url navigasi 'internal' situs, dll.
sumber
hanya untuk mendapatkan tautan, tanpa B.soup dan regex:
untuk operasi yang lebih kompleks, tentu saja BSoup masih lebih disukai.
sumber
<a
danhref
? Katakanrel="nofollow"
atauonclick="..."
atau bahkan hanya baris baru? stackoverflow.com/questions/1732348/…Script ini melakukan apa yang Anda cari, tetapi juga menyelesaikan tautan relatif ke tautan absolut.
sumber
Untuk menemukan semua tautan, dalam contoh ini kita akan menggunakan modul urllib2 bersama dengan re.module * Salah satu fungsi paling kuat dalam modul re adalah "re.findall ()". Sementara re.search () digunakan untuk menemukan kecocokan pertama untuk suatu pola, re.findall () menemukan semua kecocokan dan mengembalikannya sebagai daftar string, dengan setiap string mewakili satu kecocokan *
sumber
Mengapa tidak menggunakan ekspresi reguler:
sumber
(r"<a.*?\s*href=\"(.*?)\".*?>(.*?)</a>", page)
artinya Terima kasih!Tautan dapat berada dalam beragam atribut sehingga Anda dapat melewati daftar atribut tersebut untuk dipilih
misalnya, dengan atribut src dan href (di sini saya menggunakan operator begin dengan ^ untuk menentukan bahwa salah satu dari nilai atribut ini dimulai dengan http. Anda dapat menyesuaikan ini sesuai kebutuhan
Atribut = penyeleksi nilai
sumber
Berikut ini adalah contoh menggunakan @ars jawabannya diterima dan
BeautifulSoup4
,requests
, danwget
modul untuk menangani download.sumber
Saya menemukan jawaban oleh @ Blairg23 berfungsi, setelah koreksi berikut (mencakup skenario yang gagal berfungsi dengan benar):
Untuk Python 3:
urllib.parse.urljoin
harus digunakan untuk mendapatkan URL lengkap.sumber
Parser BeatifulSoup sendiri bisa lambat. Mungkin lebih layak menggunakan lxml yang mampu melakukan parsing langsung dari URL (dengan beberapa batasan yang disebutkan di bawah).
Kode di atas akan mengembalikan tautan apa adanya, dan dalam kebanyakan kasus mereka akan berupa tautan relatif atau absolut dari root situs. Karena use case saya hanya mengekstraksi jenis tautan tertentu, di bawah ini adalah versi yang mengubah tautan ke URL lengkap dan yang secara opsional menerima pola gumpalan seperti
*.mp3
. Itu tidak akan menangani titik tunggal dan ganda di jalur relatif, tapi sejauh ini saya tidak membutuhkannya. Jika Anda perlu fragmen URL parsing mengandung../
atau./
kemudian urlparse.urljoin mungkin akan berguna.CATATAN : Penguraian url lxml langsung tidak menangani pemuatan dari
https
dan tidak melakukan pengalihan, jadi untuk alasan ini versi di bawah ini menggunakanurllib2
+lxml
.Penggunaannya adalah sebagai berikut:
sumber
lxml
hanya dapat menangani input yang valid, bagaimana cara menggantinyaBeautifulSoup
?lxml.html
sedikit lebih lunak daripadalxml.etree
. Jika input Anda tidak terbentuk dengan baik maka Anda dapat secara eksplisit mengatur parser BeautifulSoup: lxml.de/elementsoup.html . Dan jika Anda menggunakan BeatifulSoup maka BS3 adalah pilihan yang lebih baik.sumber
Mungkin ada banyak duplikat tautan bersama dengan tautan eksternal dan internal. Untuk membedakan antara keduanya dan dapatkan tautan unik menggunakan set:
sumber