Rumah > Artikel > pembangunan bahagian belakang > Masalah semasa dan kesilapan mengikis web dalam Python dan helah untuk menyelesaikannya!
Salam! Saya Max, pembangun Python dari Ukraine, pembangun dengan kepakaran dalam mengikis web, analisis data dan pemprosesan.
Perjalanan saya dalam mengikis web bermula pada 2016 apabila saya menyelesaikan cabaran penjanaan utama untuk sebuah syarikat kecil. Pada mulanya, saya menggunakan penyelesaian luar biasa seperti Import.io dan Kimono Labs. Walau bagaimanapun, saya dengan cepat menghadapi had seperti penyekatan, pengekstrakan data yang tidak tepat dan isu prestasi. Ini membawa saya belajar Python. Itulah zaman kegemilangan apabila permintaan dan lxml/beautifulsoup sudah cukup untuk mengekstrak data daripada kebanyakan tapak web. Dan jika anda tahu cara bekerja dengan benang, anda sudah pun pakar yang dihormati :)
Salah seorang ahli komuniti kami menulis blog ini sebagai sumbangan kepada Crawlee Blog. Jika anda ingin menyumbangkan blog seperti ini kepada Crawlee Blog, sila hubungi kami di saluran perselisihan kami.
Sebagai pekerja bebas, saya telah membina penyelesaian kecil dan sistem perlombongan data yang besar dan kompleks untuk produk selama ini.
Hari ini, saya ingin membincangkan realiti mengikis web dengan Python pada tahun 2024. Kami akan melihat kesilapan yang kadangkala saya lihat dan masalah yang akan anda hadapi serta menawarkan penyelesaian kepada sesetengah daripadanya.
Mari kita mulakan.
Hanya terima permintaan dan sup cantik dan mula buat banyak wang...
Tidak, ini bukan artikel seperti itu.
Ya, ia boleh mengejutkan. Tetapi saya telah melihat mesej ini daripada pelanggan dan pembangun enam tahun lalu, empat tahun lalu dan pada tahun 2024. Saya membaca siaran di Reddit hanya beberapa bulan lalu tentang isu ini.
Mari kita lihat contoh kod mudah. Ini akan berfungsi untuk permintaan, httpx dan aiohttp dengan pemasangan yang bersih dan tiada sambungan.
import httpx url = 'https://www.wayfair.com/' headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br, zstd", "Connection": "keep-alive", } response = httpx.get(url, headers=headers) print(response.content[:10])
Hasil cetakan akan serupa dengan:
b'\x83\x0c\x00\x00\xc4\r\x8e4\x82\x8a'
Ini bukan satu ralat - ia adalah respons pelayan yang sah dengan sempurna. Ia dikodkan entah bagaimana.
Jawapannya terletak pada pengepala Accept-Encoding. Dalam contoh di atas, saya hanya menyalinnya daripada penyemak imbas saya, jadi ia menyenaraikan semua kaedah pemampatan yang disokong oleh penyemak imbas saya: "gzip, deflate, br, zstd". Bahagian belakang Wayfair menyokong pemampatan dengan "br", iaitu Brotli, dan menggunakannya sebagai kaedah paling cekap.
Ini boleh berlaku jika tiada perpustakaan yang disenaraikan di atas mempunyai kebergantungan Brotli antara kebergantungan standard mereka. Walau bagaimanapun, kesemuanya menyokong penyahmampatan daripada format ini jika anda sudah memasang Brotli.
Oleh itu, sudah memadai untuk memasang perpustakaan yang sesuai:
pip install Brotli
Ini akan membolehkan anda mendapatkan hasil cetakan:
b'<!DOCTYPE '
Anda boleh mendapatkan hasil yang sama untuk aiohttp dan httpx dengan melakukan pemasangan dengan sambungan:
pip install aiohttp[speedups] pip install httpx[brotli]
Sebenarnya, menambah pergantungan brotli ialah sumbangan pertama saya kepada crawlee-python. Mereka menggunakan httpx sebagai klien HTTP asas.
Anda mungkin juga perasan bahawa format pemampatan data baharu yang disokong zstd muncul beberapa ketika dahulu. Saya belum melihat sebarang bahagian belakang yang menggunakannya lagi, tetapi httpx akan menyokong penyahmampatan dalam versi di atas 0.28.0. Saya sudah menggunakannya untuk memampatkan pembuangan tindak balas pelayan dalam projek saya; ia menunjukkan kecekapan yang luar biasa dalam penyelesaian tak segerak dengan aiofiles.
Penyelesaian yang paling biasa untuk situasi ini yang saya lihat adalah untuk pembangun berhenti menggunakan pengepala Accept-Encoding, sekali gus mendapat respons tidak dimampatkan daripada pelayan. Kenapa teruk? Halaman utama Wayfair mengambil masa kira-kira 1 megabait tidak dimampatkan dan kira-kira 0.165 megabait dimampatkan.
Oleh itu, jika tiada pengepala ini:
Tetapi saya rasa masalahnya lebih mendalam daripada itu. Ramai pembangun pengikis web tidak memahami apa yang dilakukan oleh pengepala yang mereka gunakan. Jadi, jika ini terpakai kepada anda, apabila anda sedang mengerjakan projek anda yang seterusnya, baca perkara ini; mereka mungkin mengejutkan anda.
Ya, betul. 2023 membawa kami bukan sahaja Model Bahasa Besar seperti ChatGPT tetapi juga meningkatkan perlindungan Cloudflare.
Mereka yang telah lama mengikis web mungkin berkata, "Nah, kami telah berurusan dengan DataDome, PerimeterX, InCapsula dan seumpamanya."
Tetapi Cloudflare telah mengubah peraturan permainan. Ia adalah salah satu penyedia CDN terbesar di dunia, menyediakan sejumlah besar tapak. Oleh itu, perkhidmatannya tersedia untuk banyak laman web dengan halangan kemasukan yang agak rendah. Ini menjadikannya sangat berbeza daripada teknologi yang dinyatakan sebelum ini, yang dilaksanakan secara sengaja apabila mereka ingin melindungi tapak daripada mengikis.
Cloudflare ialah sebabnya, apabila anda mula membaca kursus lain tentang "Cara melakukan pengikisan web menggunakan permintaan dan beautifulsoup", anda boleh menutupnya serta-merta. Kerana terdapat kemungkinan besar bahawa apa yang anda pelajari tidak akan berfungsi pada mana-mana tapak web "layak".
Mari kita lihat satu lagi contoh kod mudah:
from httpx import Client client = Client(http2=True) url = 'https://www.g2.com/' headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br, zstd", "Connection": "keep-alive", } response = client.get(url, headers=headers) print(response)
Sudah tentu, jawapannya ialah 403.
Bagaimana jika kita menggunakan curl?
curl -XGET -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' -H 'Connection: keep-alive' 'https://www.g2.com/' -s -o /dev/null -w "%{http_code}\n"
Juga 403.
Mengapa ini berlaku?
Oleh kerana Cloudflare menggunakan cap jari TLS dari banyak klien HTTP yang popular di kalangan pembangun, pentadbir tapak juga boleh menyesuaikan cara agresif Cloudflare menyekat pelanggan berdasarkan cap jari ini.
Untuk curl, kita boleh menyelesaikannya seperti ini:
curl -XGET -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' -H 'Connection: keep-alive' 'https://www.g2.com/' --tlsv1.3 -s -o /dev/null -w "%{http_code}\n"
You might expect me to write here an equally elegant solution for httpx, but no. About six months ago, you could do the "dirty trick" and change the basic httpcore parameters that it passes to h2, which are responsible for the HTTP2 handshake. But now, as I'm writing this article, that doesn't work anymore.
There are different approaches to getting around this. But let's solve it by manipulating TLS.
The bad news is that all the Python clients I know of use the ssl library to handle TLS. And it doesn't give you the ability to manipulate TLS subtly.
The good news is that the Python community is great and implements solutions that exist in other programming languages.
This Python wrapper around the Golang library provides an API similar to requests.
pip install tls-client
from tls_client import Session client = Session(client_identifier="firefox_120") url = 'https://www.g2.com/' headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br, zstd", "Connection": "keep-alive", } response = client.get(url, headers=headers) print(response)
The tls_client supports TLS presets for popular browsers, the relevance of which is maintained by developers. To use this, you must pass the necessary client_identifier. However, the library also allows for subtle manual manipulation of TLS.
This wrapper around the C library patches curl and provides an API similar to requests.
pip install curl_cffi
from curl_cffi import requests url = 'https://www.g2.com/' headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br, zstd", "Connection": "keep-alive", } response = requests.get(url, headers=headers, impersonate="chrome124") print(response)
curl_cffi also provides TLS presets for some browsers, which are specified via the impersonate parameter. It also provides options for subtle manual manipulation of TLS.
I think someone just said, "They're literally doing the same thing." That's right, and they're both still very raw.
Let's do some simple comparisons:
Feature | tls_client | curl_cffi |
---|---|---|
TLS preset | + | + |
TLS manual | + | + |
async support | - | + |
big company support | - | + |
number of contributors | - | + |
Jelas sekali, curl_cffi menang dalam perbandingan ini. Tetapi sebagai pengguna aktif, saya perlu mengatakan bahawa kadang-kadang terdapat beberapa ralat yang agak aneh yang saya hanya tidak pasti bagaimana untuk menangani. Dan jujurlah, setakat ini, kedua-duanya agak mentah.
Saya rasa kita tidak lama lagi akan melihat perpustakaan lain yang menyelesaikan masalah ini.
Mungkin ada yang bertanya, bagaimana pula dengan Scrapy? Saya akan jujur: Saya tidak begitu mengikuti kemas kini mereka. Tetapi saya tidak pernah mendengar tentang Zyte melakukan apa-apa untuk memintas cap jari TLS. Jadi di luar kotak Scrapy juga akan disekat, tetapi tiada apa yang menghalang anda daripada menggunakan curl_cffi dalam Scrapy Spider anda.
Ya, kadangkala kita perlu menggunakan pelayar tanpa kepala. Walaupun saya jujur, dari sudut pandangan saya, ia digunakan terlalu kerap walaupun jelas tidak perlu.
Walaupun dalam keadaan tanpa kepala, orang di Cloudflare telah berjaya menyukarkan kehidupan rata-rata pengikis web dengan mencipta raksasa yang dipanggil Cloudflare Turnstile.
Untuk menguji alatan yang berbeza, anda boleh menggunakan halaman demo ini.
Untuk menguji dengan cepat sama ada perpustakaan berfungsi dengan penyemak imbas, anda harus bermula dengan menyemak mod tanpa kepala biasa. Anda tidak perlu menggunakan automasi; cuma buka tapak menggunakan perpustakaan yang dikehendaki dan bertindak secara manual.
Perpustakaan apakah yang patut dilawati untuk ini?
Ia akan disekat dan tidak akan membenarkan anda menyelesaikan captcha.
Penulis drama ialah perpustakaan yang hebat untuk automasi penyemak imbas. Walau bagaimanapun, pembangun dengan jelas menyatakan bahawa mereka tidak merancang untuk membangunkannya sebagai alat mengikis web.
Dan saya tidak pernah mendengar sebarang projek Python yang menyelesaikan masalah ini dengan berkesan.
Ia akan disekat dan tidak akan membenarkan anda menyelesaikan captcha.
Ini adalah perpustakaan yang agak biasa untuk bekerja dengan penyemak imbas tanpa kepala dalam Python, dan dalam beberapa kes, ia membenarkan memintas Cloudflare Turnstile. Tetapi pada laman web sasaran, ia disekat. Selain itu, dalam projek saya, saya telah menemui sekurang-kurangnya dua kes lain di mana Cloudflare menyekat undetected_chromedriver.
Secara amnya, undetected_chromedriver ialah perpustakaan yang bagus untuk projek anda, terutamanya kerana ia menggunakan Selenium lama yang bagus di bawah hud.
Ia membolehkan anda melepasi captcha selepas mengklik.
Saya tidak tahu bagaimana pembangunnya melakukan perkara ini, tetapi ia berfungsi. Ciri utamanya ialah ia dibangunkan khusus untuk mengikis web. Ia juga mempunyai perpustakaan peringkat lebih tinggi untuk digunakan - botasaurus.
Pada sisi negatifnya, setakat ini, ia agak mentah, dan botasaurus-driver tidak mempunyai dokumentasi dan mempunyai API yang agak mencabar untuk digunakan.
Untuk meringkaskan, kemungkinan besar, perpustakaan utama anda untuk penyemakan imbas tanpa kepala akan menjadi undetected_chromedriver. Tetapi dalam beberapa kes yang sangat mencabar, anda mungkin perlu menggunakan botasaurus.
Rangka kerja peringkat tinggi direka bentuk untuk mempercepat dan memudahkan pembangunan dengan membenarkan kami menumpukan pada logik perniagaan, walaupun kami sering membayar harga dalam fleksibiliti dan kawalan.
Jadi, apakah rangka kerja untuk mengikis web pada tahun 2024?
Adalah mustahil untuk bercakap tentang rangka kerja mengikis web Python tanpa menyebut Scrapy. Scrapinghub (kini Zyte) pertama kali mengeluarkannya pada 2008. Selama 16 tahun, ia telah dibangunkan sebagai perpustakaan sumber terbuka di mana syarikat pembangunan membina penyelesaian perniagaan mereka.
Bercakap tentang kelebihan Scrapy, anda boleh menulis artikel berasingan. Tetapi saya akan menekankan mereka berdua:
Tetapi apakah kelemahannya?
Dalam beberapa tahun kebelakangan ini, Zyte telah memberi lebih tumpuan kepada membangunkan platformnya sendiri. Scrapy kebanyakannya mendapat pembetulan sahaja.
Oleh itu, Scrapy ialah penyelesaian yang baik dan terbukti untuk tapak yang tidak dilindungi daripada pengikisan web. Anda perlu membangunkan dan menambah penyelesaian yang diperlukan pada rangka kerja untuk memintas langkah anti-mengikis.
Rangka kerja baharu untuk mengikis web menggunakan automasi penyemak imbas, dibina pada pemacu botasaurus. Komitmen awal dibuat pada 9 Mei 2023.
Mari kita mulakan dengan kelebihannya:
Keburukan termasuk:
Ini ialah rangka kerja yang baik untuk membina pengikis web dengan cepat berdasarkan automasi penyemak imbas. Ia tidak mempunyai fleksibiliti dan sokongan untuk klien HTTP, yang penting untuk pengguna seperti saya.
Rangka kerja baharu untuk mengikis web dalam ekosistem Python. Komitmen awal dibuat pada 10 Jan 2024, dengan keluaran di ruang media pada 5 Julai 2024.
Crawlee meliputi rangkak dan pengikisan anda dari hujung ke hujung dan membantu anda membina pengikis yang boleh dipercayai. Cepat.
? Crawlee for Python terbuka kepada pengguna awal!
Perangkak anda akan kelihatan hampir seperti manusia dan terbang di bawah radar perlindungan bot moden walaupun dengan konfigurasi lalai. Crawlee memberi anda alatan untuk merangkak web untuk pautan, mengikis data dan menyimpannya secara berterusan dalam format yang boleh dibaca mesin, tanpa perlu risau tentang butiran teknikal. Dan terima kasih kepada pilihan konfigurasi yang kaya, anda boleh mengubah suai hampir mana-mana aspek Crawlee agar sesuai dengan keperluan projek anda jika tetapan lalai tidak memotongnya.
? Lihat dokumentasi penuh, panduan dan contoh di tapak web projek Crawlee ?
Kami juga mempunyai pelaksanaan TypeScript bagi Crawlee, yang boleh anda terokai dan gunakan untuk projek anda. Lawati repositori GitHub kami untuk mendapatkan maklumat lanjut Crawlee untuk JS/TS di GitHub.
Kami…
Dibangunkan oleh Apify, ia ialah adaptasi Python daripada rangka kerja JS terkenal mereka, yang pertama kali dikeluarkan pada 9 Jul 2019.
Memandangkan ini adalah penyelesaian yang benar-benar baharu di pasaran, ia kini dalam peringkat reka bentuk dan pembangunan yang aktif. Masyarakat juga terlibat secara aktif dalam pembangunannya. Jadi, kita dapat melihat bahawa penggunaan curl_cffi sudah dibincangkan. Kemungkinan mencipta pelanggan berasaskan Rust mereka sendiri telah dibincangkan sebelum ini. Saya harap syarikat tidak meninggalkan idea itu.
Daripada pasukan Crawlee:
"Ya, pastinya kami akan terus menambah baik Crawlee untuk Python untuk tahun-tahun akan datang."
Seperti yang saya sendiri ingin melihat klien HTTP untuk Python dibangunkan dan diselenggara oleh syarikat besar. Dan Rust menunjukkan dirinya dengan baik sebagai bahasa perpustakaan untuk Python. Mari kita ingat sekurang-kurangnya Ruff dan Pydantic v2.
Kelebihan:
Rangka kerja telah dibangunkan oleh sebuah syarikat yang mantap dalam pasaran web scraping, yang mempunyai kepakaran yang dibangunkan dengan baik dalam bidang ini.
Secara berasingan, ia mempunyai seni bina modular yang cukup bagus. Jika pembangun memperkenalkan keupayaan untuk bertukar antara beberapa klien HTTP, kami akan mendapat rangka kerja yang agak fleksibel yang membolehkan kami menukar teknologi yang digunakan dengan mudah, dengan pelaksanaan mudah daripada pasukan pembangunan.
Kekurangan:
Saya percaya betapa berjayanya crawlee-python bergantung terutamanya kepada komuniti. Oleh kerana bilangan tutorial yang kecil, ia tidak sesuai untuk pemula. Walau bagaimanapun, pembangun berpengalaman mungkin memutuskan untuk mencubanya dan bukannya Scrapy.
Dalam jangka masa panjang, ia mungkin menjadi penyelesaian yang lebih baik daripada Scrapy dan Botasaurus. Ia sudah menyediakan alat yang fleksibel untuk bekerja dengan klien HTTP, mengautomasikan penyemak imbas di luar kotak, dan menukar antara mereka dengan cepat. Walau bagaimanapun, ia tidak mempunyai alat untuk memintas perlindungan mengikis dan pelaksanaannya pada masa hadapan mungkin menjadi faktor penentu dalam memilih rangka kerja untuk anda.
Jika anda telah membaca sehingga ke sini, saya anggap anda mendapati ia menarik dan mungkin juga membantu :)
Industri sedang berubah dan menawarkan cabaran baharu, dan jika anda terlibat secara profesional dalam mengikis web, anda perlu memerhatikan keadaan dengan teliti. Dalam beberapa bidang lain, anda akan kekal sebagai pembangun yang membuat produk menggunakan teknologi lapuk. Tetapi dalam pengikisan web moden, anda menjadi pembangun yang membuat pengikis web yang tidak berfungsi.
Selain itu, jangan lupa bahawa anda adalah sebahagian daripada komuniti Python yang lebih besar, dan pengetahuan anda boleh berguna dalam membangunkan alatan yang membuat sesuatu berlaku untuk kita semua. Seperti yang anda lihat, banyak alatan yang anda perlukan sedang dibina secara literal sekarang.
Saya akan gembira membaca ulasan anda. Selain itu, jika anda memerlukan pakar mengikis web atau adakah anda hanya ingin membincangkan artikel tersebut, anda boleh menemui saya di platform berikut: Github, Linkedin, Apify, Upwork, Contra.
Terima kasih atas perhatian anda :)
Atas ialah kandungan terperinci Masalah semasa dan kesilapan mengikis web dalam Python dan helah untuk menyelesaikannya!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!