Trong chương này, chúng ta hãy tìm hiểu cách thực hiện quét web trên các trang web động và các khái niệm liên quan một cách chi tiết
Giới thiệu
Quét web là một nhiệm vụ phức tạp và độ phức tạp sẽ nhân lên nếu trang web động. Theo Kiểm toán toàn cầu về khả năng truy cập web của Liên hợp quốc, hơn 70% trang web có bản chất động và chúng dựa vào JavaScript cho các chức năng của chúng
Ví dụ trang web động
Chúng ta hãy xem một ví dụ về một trang web động và biết lý do tại sao nó khó cạo. Ở đây chúng ta sẽ lấy ví dụ tìm kiếm từ một trang web có tên http. //thí dụ. rút trích nội dung trang web. com/địa điểm/mặc định/tìm kiếm. Nhưng làm thế nào chúng ta có thể nói rằng trang web này có tính chất động?
import re import urllib.request response = urllib.request.urlopen['//example.webscraping.com/places/default/search'] html = response.read[] text = html.decode[] re.findall['[.*?]',text]
đầu ra
[ ]
Đầu ra ở trên cho thấy rằng trình quét ví dụ không thể trích xuất thông tin vì
phần tử chúng tôi đang cố tìm trống
Phương pháp thu thập dữ liệu từ các trang web động
Chúng tôi đã thấy rằng trình quét không thể lấy thông tin từ một trang web động vì dữ liệu được tải động bằng JavaScript. Trong những trường hợp như vậy, chúng ta có thể sử dụng hai kỹ thuật sau để lấy dữ liệu từ các trang web phụ thuộc JavaScript động -
- Kỹ thuật đảo ngược JavaScript
- Kết xuất JavaScript
Kỹ thuật đảo ngược JavaScript
Quy trình được gọi là kỹ thuật đảo ngược sẽ hữu ích và giúp chúng tôi hiểu cách dữ liệu được tải động bởi các trang web
Để thực hiện việc này, chúng tôi cần nhấp vào tab kiểm tra phần tử cho một URL được chỉ định. Tiếp theo, chúng tôi sẽ nhấp vào tab MẠNG để tìm tất cả các yêu cầu được thực hiện cho trang web đó bao gồm cả tìm kiếm. json với đường dẫn /ajax. Thay vì truy cập dữ liệu AJAX từ trình duyệt hoặc qua tab MẠNG, chúng ta cũng có thể làm điều đó với sự trợ giúp của tập lệnh Python sau -
import requests url=requests.get['//example.webscraping.com/ajax/search.json?page=0&page_size=10&search_term=a'] url.json[]
Thí dụ
Đoạn script trên cho phép chúng ta truy cập phản hồi JSON bằng cách sử dụng phương thức json của Python. Tương tự, chúng ta có thể tải xuống phản hồi chuỗi thô và bằng cách sử dụng json của python. loading, chúng ta cũng có thể tải nó. Chúng tôi đang làm điều này với sự trợ giúp của tập lệnh Python sau. Về cơ bản, nó sẽ quét tất cả các quốc gia bằng cách tìm kiếm chữ cái của bảng chữ cái 'a' và sau đó lặp lại các trang kết quả của các phản hồi JSON
import requests import string PAGE_SIZE = 15 url = '//example.webscraping.com/ajax/' + 'search.json?page={}&page_size={}&search_term=a' countries = set[] for letter in string.ascii_lowercase: print['Searching with %s' % letter] page = 0 while True: response = requests.get[url.format[page, PAGE_SIZE, letter]] data = response.json[] print['adding %d records from the page %d' %[len[data.get['records']],page]] for record in data.get['records']:countries.add[record['country']] page += 1 if page >= data['num_pages']: break with open['countries.txt', 'w'] as countries_file: countries_file.write['n'.join[sorted[countries]]]
Sau khi chạy đoạn mã trên, chúng tôi sẽ nhận được đầu ra sau và các bản ghi sẽ được lưu trong tệp có tên quốc gia. txt
đầu ra
Searching with a adding 15 records from the page 0 adding 15 records from the page 1 ...
Kết xuất JavaScript
Trong phần trước, chúng tôi đã thực hiện kỹ thuật đảo ngược trên trang web về cách API hoạt động và cách chúng tôi có thể sử dụng nó để truy xuất kết quả trong một yêu cầu. Tuy nhiên, chúng ta có thể gặp phải những khó khăn sau khi thực hiện kỹ thuật đảo ngược -
Đôi khi các trang web có thể rất khó khăn. Ví dụ: nếu trang web được tạo bằng công cụ trình duyệt nâng cao, chẳng hạn như Google Web Toolkit [GWT], thì mã JS kết quả sẽ được tạo bằng máy và khó hiểu và kỹ sư đảo ngược
Một số framework cấp cao hơn như React. js có thể gây khó khăn cho kỹ thuật đảo ngược bằng cách trừu tượng hóa logic JavaScript vốn đã phức tạp
Giải pháp cho những khó khăn trên là sử dụng công cụ kết xuất trình duyệt phân tích cú pháp HTML, áp dụng định dạng CSS và thực thi JavaScript để hiển thị trang web
Thí dụ
Trong ví dụ này, để hiển thị Java Script, chúng ta sẽ sử dụng mô-đun Python quen thuộc Selenium. Mã Python sau đây sẽ hiển thị một trang web với sự trợ giúp của Selenium -
Internet mở rộng các trang web nhanh và hiện đại thường sử dụng cơ chế tải nội dung động để cung cấp trải nghiệm người dùng tốt nhất. Tuy nhiên, mặt khác, việc trích xuất dữ liệu từ các trang web như vậy trở nên khó khăn hơn vì nó yêu cầu thực thi Javascript nội bộ trong ngữ cảnh trang trong khi cạo. Hãy xem xét một số kỹ thuật thông thường cho phép trích xuất dữ liệu từ các trang web động bằng Python
Trang web động là gì?
Trang web động là loại trang web có thể cập nhật hoặc tải nội dung sau khi tải HTML ban đầu. Vì vậy, trình duyệt nhận HTML cơ bản bằng JS và sau đó tải nội dung bằng mã Javascript đã nhận. Cách tiếp cận như vậy cho phép tăng tốc độ tải trang và ngăn tải lại cùng một bố cục mỗi khi bạn muốn mở một trang mới
Thông thường, các trang web động sử dụng AJAX để tải nội dung động hoặc thậm chí toàn bộ trang web dựa trên công nghệ Ứng dụng một trang [SPA]
Ngược lại với các trang web động, chúng tôi có thể quan sát các trang web tĩnh chứa tất cả nội dung được yêu cầu khi tải trang
Một ví dụ tuyệt vời về trang web tĩnh là
window.addEventListener["DOMContentLoaded", function[] {
document.getElementById["test"].innerHTML = "I ❤️ ScrapingAnt"
}, false];
6Toàn bộ nội dung của trang web này được tải dưới dạng HTML đơn giản trong khi tải trang ban đầu
Để chứng minh ý tưởng cơ bản của một trang web động, chúng ta có thể tạo một trang web chứa văn bản được hiển thị động. Nó sẽ không bao gồm bất kỳ yêu cầu lấy thông tin nào, chỉ là kết xuất của một HTML khác sau khi tải trang
Dynamic Web Page Example
window.addEventListener["DOMContentLoaded", function[] {
document.getElementById["test"].innerHTML = "I ❤️ ScrapingAnt"
}, false];
Web Scraping is hard
Tất cả những gì chúng tôi có ở đây là một tệp HTML có một
window.addEventListener["DOMContentLoaded", function[] {
document.getElementById["test"].innerHTML = "I ❤️ ScrapingAnt"
}, false];
7 duy nhất trong phần nội dung có chứa văn bản -
window.addEventListener["DOMContentLoaded", function[] {
document.getElementById["test"].innerHTML = "I ❤️ ScrapingAnt"
}, false];
8, nhưng sau khi tải trang, văn bản đó được thay thế bằng văn bản do Javascript tạo ra
window.addEventListener["DOMContentLoaded", function[] {
document.getElementById["test"].innerHTML = "I ❤️ ScrapingAnt"
}, false];
Để chứng minh điều này, hãy mở trang này trong trình duyệt và quan sát văn bản được thay thế động
Được rồi, vì vậy trình duyệt sẽ hiển thị một văn bản và các thẻ HTML sẽ bọc văn bản này.
Chúng tôi không thể sử dụng BeautifulSoup hoặc LXML để phân tích cú pháp? .
Trích xuất dữ liệu từ một trang web động
BeautifulSoup là một trong những thư viện Python phổ biến nhất trên Internet để phân tích cú pháp HTML. Gần 80% các hướng dẫn về Python quét web sử dụng thư viện này để trích xuất nội dung cần thiết từ HTML
Hãy sử dụng BeautifulSoup để trích xuất văn bản bên trong
window.addEventListener["DOMContentLoaded", function[] {
document.getElementById["test"].innerHTML = "I ❤️ ScrapingAnt"
}, false];
7 từ mẫu của chúng tôi ở trên[ ]1
Đoạn mã này sử dụng thư viện
[ ]10 để mở tệp HTML thử nghiệm của chúng tôi [
[ ]11] từ thư mục cục bộ và tạo một phiên bản của thư viện BeautifulSoup được lưu trữ trong biến
[ ]12. Sử dụng
[ ]12, chúng tôi tìm thấy thẻ có id
[ ]14 và trích xuất văn bản từ đó
Trong ảnh chụp màn hình từ phần bài viết đầu tiên, chúng ta đã thấy rằng nội dung của trang thử nghiệm là
[ ]15, nhưng đầu ra của đoạn mã như sau
[ ]8
Và kết quả khác với mong đợi của chúng tôi [ngoại trừ việc bạn đã biết chuyện gì đang xảy ra ở đó]. Mọi thứ đều chính xác theo quan điểm của BeautifulSoup - nó đã phân tích cú pháp dữ liệu từ tệp HTML được cung cấp, nhưng chúng tôi muốn nhận được kết quả giống như trình duyệt hiển thị. Lý do là Javascript động không được thực thi trong quá trình phân tích cú pháp HTML
Chúng tôi cần chạy HTML trong trình duyệt để xem các giá trị chính xác và sau đó có thể nắm bắt các giá trị đó theo chương trình
Dưới đây, bạn có thể tìm thấy bốn cách khác nhau để thực thi Javascript của trang web động và cung cấp dữ liệu hợp lệ cho trình phân tích cú pháp HTML. Selenium, Pyppeteer, Playwright và Web Scraping API
selen. quét web bằng trình điều khiển web
Selenium là một trong những công cụ tự động hóa trình duyệt web phổ biến nhất dành cho Python. Nó cho phép giao tiếp với các trình duyệt web khác nhau bằng cách sử dụng một trình kết nối đặc biệt - webdriver
Để sử dụng Selenium với Chrome/Chromium, chúng ta cần tải webdriver từ kho lưu trữ và đặt nó vào thư mục dự án. Đừng quên cài đặt Selenium bằng cách thực thi
[ ]9
Luồng khởi tạo và cạo Selenium như sau
- xác định và thiết lập biến đường dẫn Chrome
- xác định và thiết lập biến đường dẫn trình duyệt web Chrome
- xác định các đối số khởi chạy trình duyệt [để sử dụng chế độ không đầu, proxy, v.v. ]
- khởi tạo một webdriver với các tùy chọn được xác định ở trên
- tải một trang web thông qua webdriver khởi tạo
Trong phối cảnh mã, nó trông như sau
import requests url=requests.get['//example.webscraping.com/ajax/search.json?page=0&page_size=10&search_term=a'] url.json[]0
Và cuối cùng, chúng tôi sẽ nhận được kết quả cần thiết
import requests url=requests.get['//example.webscraping.com/ajax/search.json?page=0&page_size=10&search_term=a'] url.json[]1
Việc sử dụng Selenium để quét trang web động bằng Python không phức tạp và cho phép bạn chọn một trình duyệt cụ thể với phiên bản của nó nhưng bao gồm một số thành phần chuyển động cần được duy trì. Bản thân mã chứa một số phần soạn sẵn như thiết lập trình duyệt, webdriver, v.v.
Tôi thích sử dụng Selenium cho dự án quét web của mình, nhưng bạn có thể tìm thấy những cách dễ dàng hơn để trích xuất dữ liệu từ các trang web động bên dưới
người lùn. Python không đầu Chrome
Pyppeteer là một cổng Python không chính thức của Puppeteer JavaScript [không đầu] thư viện tự động hóa trình duyệt Chrome/Chromium. Nó có khả năng chủ yếu làm giống như Puppeteer có thể, nhưng sử dụng Python thay vì NodeJS
Puppeteer là một API cấp cao để điều khiển headless Chrome, vì vậy nó cho phép bạn tự động hóa các hành động mà bạn đang thực hiện thủ công với trình duyệt. sao chép văn bản của trang, tải xuống hình ảnh, lưu trang dưới dạng HTML, PDF, v.v.
Để cài đặt Pyppeteer, bạn có thể thực hiện lệnh sau
import requests url=requests.get['//example.webscraping.com/ajax/search.json?page=0&page_size=10&search_term=a'] url.json[]2
Việc sử dụng Pyppeteer cho nhu cầu của chúng ta đơn giản hơn nhiều so với Selenium
import requests url=requests.get['//example.webscraping.com/ajax/search.json?page=0&page_size=10&search_term=a'] url.json[]3
Tôi đã cố gắng bình luận về mọi phần nguyên tử của mã để hiểu rõ hơn. Tuy nhiên, nói chung, chúng tôi vừa mở một trang trình duyệt, tải tệp HTML cục bộ vào đó và trích xuất HTML được hiển thị cuối cùng để xử lý BeautifulSoup thêm
Như chúng ta có thể mong đợi, kết quả là như sau
import requests url=requests.get['//example.webscraping.com/ajax/search.json?page=0&page_size=10&search_term=a'] url.json[]1
Chúng tôi đã làm lại và không phải lo lắng về việc tìm kiếm, tải xuống và kết nối webdriver với trình duyệt. Mặc dù vậy, Pyppeteer trông có vẻ bị bỏ hoang và không được bảo trì đúng cách. Tình trạng này có thể thay đổi trong tương lai gần nhất, nhưng tôi khuyên bạn nên xem thư viện mạnh mẽ hơn
nhà viết kịch. Tự động hóa trình duyệt Chromium, Firefox và Webkit
Playwright có thể được coi là một Puppeteer mở rộng, vì nó cho phép sử dụng nhiều loại trình duyệt hơn [Chromium, Firefox và Webkit] để tự động kiểm tra và quét ứng dụng web hiện đại. Bạn có thể sử dụng Playwright API trong JavaScript & TypeScript, Python, C# và Java. Và thật tuyệt vời, vì những người duy trì Playwright ban đầu hỗ trợ Python
API gần giống như đối với Pyppeteer, nhưng có cả phiên bản đồng bộ hóa và không đồng bộ
Cài đặt đơn giản như mọi khi
window.addEventListener["DOMContentLoaded", function[] {
document.getElementById["test"].innerHTML = "I ❤️ ScrapingAnt"
}, false];
0Hãy viết lại ví dụ trước bằng Playwright
window.addEventListener["DOMContentLoaded", function[] {
document.getElementById["test"].innerHTML = "I ❤️ ScrapingAnt"
}, false];
1Như một truyền thống tốt đẹp, chúng ta có thể quan sát đầu ra yêu quý của mình
import requests url=requests.get['//example.webscraping.com/ajax/search.json?page=0&page_size=10&search_term=a'] url.json[]1
Chúng ta đã trải qua một số phương pháp trích xuất dữ liệu khác nhau với Python, nhưng có cách nào đơn giản hơn để thực hiện công việc này không?
Gặp gỡ API quét web
API quét web
API cạo web ScrapingAnt cung cấp khả năng cạo các trang web động chỉ bằng một lệnh gọi API. Nó đã xử lý Chrome không đầu và proxy xoay vòng, vì vậy phản hồi được cung cấp sẽ bao gồm nội dung được hiển thị bằng Javascript. Cuộc thăm dò proxy của ScrapingAnt ngăn chặn và cung cấp tỷ lệ trích xuất dữ liệu cao và liên tục
Việc sử dụng API quét web là tùy chọn đơn giản nhất và chỉ yêu cầu các kỹ năng lập trình cơ bản
Bạn không cần duy trì trình duyệt, thư viện, proxy, trình điều khiển web hoặc mọi khía cạnh khác của trình quét web và tập trung vào phần thú vị nhất của công việc - phân tích dữ liệu
Vì API quét web chạy trên máy chủ đám mây, chúng tôi phải phân phối tệp của mình ở đâu đó để kiểm tra tệp. Tôi đã tạo một kho lưu trữ với một tệp duy nhất. https. //github. com/kami4ka/dynamic-website-example/blob/main/index. html
URL thử nghiệm cuối cùng để thu thập dữ liệu web động có giao diện sau. https. // kami4ka. github. io/động-trang web-ví dụ/
Bản thân mã cạo là mã đơn giản nhất trong cả bốn thư viện được mô tả. Chúng tôi sẽ sử dụng thư viện ScrapingAntClient để truy cập API quét web
Trước tiên hãy cài đặt
window.addEventListener["DOMContentLoaded", function[] {
document.getElementById["test"].innerHTML = "I ❤️ ScrapingAnt"
}, false];
3Và sử dụng thư viện đã cài đặt
window.addEventListener["DOMContentLoaded", function[] {
document.getElementById["test"].innerHTML = "I ❤️ ScrapingAnt"
}, false];
4Ghi chú
Để nhận mã thông báo API của bạn, vui lòng truy cập trang Đăng nhập để ủy quyền trong bảng điều khiển Người dùng ScrapingAnt. Nó miễn phí
Và kết quả vẫn là yêu cầu
import requests url=requests.get['//example.webscraping.com/ajax/search.json?page=0&page_size=10&search_term=a'] url.json[]1
Tất cả điều kỳ diệu của trình duyệt không đầu đều xảy ra trên đám mây, vì vậy bạn cần thực hiện lệnh gọi API để nhận kết quả
Kiểm tra tài liệu để biết thêm thông tin về ScrapingAnt API
tóm tắt
Hôm nay chúng tôi đã kiểm tra bốn công cụ miễn phí cho phép quét các trang web động bằng Python. Tất cả các thư viện này đều sử dụng trình duyệt không đầu [hoặc API có trình duyệt không đầu] để hiển thị chính xác Javascript nội bộ bên trong trang HTML. Dưới đây, bạn có thể tìm thấy các liên kết để tìm hiểu thêm thông tin về các công cụ đó và chọn công cụ tốt nhất