& nbsp; · 12 phút Đọc · Cập nhật tháng 5 năm 2022 · Xóa web · 12 min read · Updated may 2022 · Web Scraping
Một trong những nhiệm vụ thách thức nhất trong việc cạo web là có thể đăng nhập tự động và trích xuất dữ liệu trong tài khoản của bạn trên trang web đó. Trong hướng dẫn này, bạn sẽ tìm hiểu làm thế nào bạn có thể trích xuất tất cả các biểu mẫu từ các trang web và điền và gửi chúng bằng các thư viện yêu cầu_html và đẹp.requests_html and BeautifulSoup libraries.
Để bắt đầu, hãy cài đặt chúng:
pip3 install requests_html bs4
Liên quan: Cách tự động hóa đăng nhập bằng Selenium trong Python. How to Automate Login using Selenium in Python.
Trích xuất các biểu mẫu từ các trang web
Mở một tập tin mới. Tôi đang gọi nó là form_extractor.py:form_extractor.py:
from bs4 import BeautifulSoup
from requests_html import HTMLSession
from pprint import pprint
Để bắt đầu, chúng tôi cần một cách để đảm bảo rằng sau khi thực hiện các yêu cầu đến trang web đích, chúng tôi đang lưu trữ các cookie được cung cấp bởi trang web đó để chúng tôi có thể duy trì phiên:
# initialize an HTTP session
session = HTMLSession[]
Bây giờ biến
8 là một phiên tiêu thụ cho sự tồn tại của cookie; Chúng tôi sẽ sử dụng biến này ở mọi nơi trong mã của chúng tôi. Chúng ta hãy viết một chức năng cung cấp URL, yêu cầu trang đó, trích xuất tất cả các thẻ biểu mẫu HTML từ nó và sau đó trả về chúng [dưới dạng danh sách]:from bs4 import BeautifulSoup
from requests_html import HTMLSession
from pprint import pprint
def get_all_forms[url]:
"""Returns all form tags found on a web page's `url` """
# GET request
res = session.get[url]
# for javascript driven website
# res.html.render[]
soup = BeautifulSoup[res.html.html, "html.parser"]
return soup.find_all["form"]
Bạn có thể nhận thấy rằng tôi đã nhận xét rằng dòng res.html.render [] thực thi javaScript trước khi cố gắng trích xuất bất cứ điều gì, vì một số trang web tải nội dung của họ bằng cách sử dụng javaScript, giải phóng nó nếu bạn cảm thấy trang web đang sử dụng javascript để tải các biểu mẫu.res.html.render[] line executes Javascript before trying to extract anything, as some websites load their content dynamically using Javascript, uncomment it if you feel that the website is using Javascript to load forms.
Vì vậy, hàm trên sẽ có thể trích xuất tất cả các biểu mẫu từ một trang web, nhưng chúng tôi cần một cách để trích xuất các chi tiết của từng biểu mẫu, chẳng hạn như đầu vào, biểu mẫu
9 [from bs4 import BeautifulSoup
from requests_html import HTMLSession
from pprint import pprint
0, # initialize an HTTP session
session = HTMLSession[]
1, # initialize an HTTP session
session = HTMLSession[]
2, v.v.] và # initialize an HTTP session
session = HTMLSession[]
3 [URL mục tiêu cho biểu mẫu đệ trình], hàm dưới đây làm điều đó:# initialize an HTTP session
session = HTMLSession[]
def get_form_details[form]:
"""Returns the HTML details of a form,
including action, method and list of form controls [inputs, etc]"""
details = {}
# get the form action [requested URL]
action = form.attrs.get["action"].lower[]
# get the form method [POST, GET, DELETE, etc]
# if not specified, GET is the default in HTML
method = form.attrs.get["method", "get"].lower[]
# get all form inputs
inputs = []
for input_tag in form.find_all["input"]:
# get type of input form control
input_type = input_tag.attrs.get["type", "text"]
# get name attribute
input_name = input_tag.attrs.get["name"]
# get the default value of that input tag
input_value =input_tag.attrs.get["value", ""]
# add everything to that list
inputs.append[{"type": input_type, "name": input_name, "value": input_value}]
Trên đây chỉ chịu trách nhiệm trích xuất các thẻ HTML đầu vào. Hãy trích xuất
4S và # initialize an HTTP session
session = HTMLSession[]
5S:# initialize an HTTP session
session = HTMLSession[]
for select in form.find_all["select"]:
# get the name attribute
select_name = select.attrs.get["name"]
# set the type as select
select_type = "select"
select_options = []
# the default select value
select_default_value = ""
# iterate over options and get the value of each
for select_option in select.find_all["option"]:
# get the option value used to submit the form
option_value = select_option.attrs.get["value"]
if option_value:
select_options.append[option_value]
if select_option.attrs.get["selected"]:
# if 'selected' attribute is set, set this option as default
select_default_value = option_value
if not select_default_value and select_options:
# if the default is not set, and there are options, take the first option as default
select_default_value = select_options[0]
# add the select to the inputs list
inputs.append[{"type": select_type, "name": select_name, "values": select_options, "value": select_default_value}]
for textarea in form.find_all["textarea"]:
# get the name attribute
textarea_name = textarea.attrs.get["name"]
# set the type as textarea
textarea_type = "textarea"
# get the textarea value
textarea_value = textarea.attrs.get["value", ""]
# add the textarea to the inputs list
inputs.append[{"type": textarea_type, "name": textarea_name, "value": textarea_value}]
Đầu tiên cho chiết xuất vòng lặp tất cả các thẻ
4 trong biểu mẫu. Chúng tôi cũng nhận được tất cả các tùy chọn có sẵn và thêm chúng vào các chi tiết biểu mẫu. Vòng lặp thứ hai là về việc tìm các thẻ # initialize an HTTP session
session = HTMLSession[]
5 và thêm chúng vào hình thức chi tiết, hoàn thành chức năng:# initialize an HTTP session
session = HTMLSession[]
# put everything to the resulting dictionary
details["action"] = action
details["method"] = method
details["inputs"] = inputs
return details
Lưu ý: Bạn luôn có thể kiểm tra toàn bộ mã trên trang này. You can always check the entire code on this page.
Bây giờ chúng ta hãy thử các chức năng này trước khi chúng ta đi sâu vào các biểu mẫu:
if __name__ == "__main__":
import sys
# get URL from the command line
url = sys.argv[1]
# get all form tags
forms = get_all_forms[url]
# iteratte over forms
for i, form in enumerate[forms, start=1]:
form_details = get_form_details[form]
print["="*50, f"form #{i}", "="*50]
print[form_details]
Tôi đã sử dụng & nbsp; liệt kê [] & nbsp; chỉ để đánh số các biểu mẫu được trích xuất. Hãy lưu tệp Python dưới dạng
8 và chạy nó:enumerate[] just for numerating extracted forms. Let's save the Python file as # initialize an HTTP session
session = HTMLSession[]
8 and run it:# initialize an HTTP session
session = HTMLSession[]
$ python form_extractor.py //wikipedia.org
Dưới đây là đầu ra trong trường hợp trang chủ của Wikipedia:
================================================== form #1 ==================================================
{'action': '//www.wikipedia.org/search-redirect.php',
'inputs': [{'name': 'family', 'type': 'hidden', 'value': 'Wikipedia'},
{'name': 'language', 'type': 'hidden', 'value': 'en'},
{'name': 'search', 'type': 'search', 'value': ''},
{'name': 'go', 'type': 'hidden', 'value': 'Go'},
{'name': 'language',
'type': 'select',
'value': 'en',
'values': ['af', 'pl', 'sk', 'ar', 'ast', 'az', 'bg', 'nan', 'bn', 'be', 'ca', 'cs', 'cy', 'da', 'de', 'et', 'el', 'en', 'es', 'eo', 'eu', 'fa', 'fr', 'gl', 'hy', 'hi', 'hr', 'id', 'it', 'he', 'ka', 'la', 'lv', 'lt', 'hu', 'mk', 'arz', 'ms', 'min', 'nl', 'ja', 'no', 'nn', 'ce', 'uz', 'pt', 'kk', 'ro', 'ru', 'simple', 'ceb', 'sl', 'sr', 'sh', 'sv', 'ta', 'tt', 'th', 'tg', 'azb', 'tr', 'uk', 'ur', 'vi', 'vo', 'war', 'zh-yue', 'zh','my']}],
'method': 'get'}
Như bạn có thể thấy, nếu bạn cố gắng vào trang đó bằng trình duyệt của mình, bạn sẽ thấy một hộp tìm kiếm wikipedia đơn giản. Đó là lý do tại sao chúng ta chỉ thấy một hình thức ở đây.
Tìm hiểu thêm: & nbsp; Cách tải xuống tất cả các hình ảnh từ một trang web trong Python. How to Download All Images from a Web Page in Python.
Gửi biểu mẫu web
Bạn cũng có thể nhận thấy rằng hầu hết các trường đầu vào được trích xuất trước đó đều có loại
9; Chúng tôi không quan tâm đến điều đó. Thay vào đó, chúng ta cần điền vào đầu vào trong đó nó có tên là "Tìm kiếm" và loại "Tìm kiếm", đó là trường duy nhất có thể nhìn thấy cho người dùng thông thường. Tổng quát hơn, chúng tôi tìm kiếm bất kỳ trường đầu vào nào không được ẩn cho người dùng, bao gồm các trường # initialize an HTTP session
session = HTMLSession[]
4 và # initialize an HTTP session
session = HTMLSession[]
5."search" and type of "search", that's the only visible field for the typical user. More generally, we look for any input field that is not hidden for the user, including # initialize an HTTP session
session = HTMLSession[]
4 and # initialize an HTTP session
session = HTMLSession[]
5 fields.# initialize an HTTP session
session = HTMLSession[]
Mở một tập tin Python mới. Tôi sẽ gọi nó là
2 và nhập các thư viện mà chúng tôi sẽ cần:def get_all_forms[url]:
"""Returns all form tags found on a web page's `url` """
# GET request
res = session.get[url]
# for javascript driven website
# res.html.render[]
soup = BeautifulSoup[res.html.html, "html.parser"]
return soup.find_all["form"]
from bs4 import BeautifulSoup
from requests_html import HTMLSession
from pprint import pprint
0Chúng tôi đang lấy các chức năng mà chúng tôi đã làm trước đó từ tệp
8, hãy bắt đầu sử dụng chúng.# initialize an HTTP session
session = HTMLSession[]
Đầu tiên, chúng ta hãy trích xuất tất cả các biểu mẫu có sẵn và in chúng vào màn hình:
from bs4 import BeautifulSoup
from requests_html import HTMLSession
from pprint import pprint
1Bây giờ để làm cho mã của chúng tôi linh hoạt nhất có thể [trong đó chúng tôi có thể chạy cho bất kỳ trang web nào], hãy nhắc người dùng tập lệnh chọn biểu mẫu nào để gửi:
from bs4 import BeautifulSoup
from requests_html import HTMLSession
from pprint import pprint
2Bây giờ hãy xây dựng dữ liệu gửi của chúng tôi:
from bs4 import BeautifulSoup
from requests_html import HTMLSession
from pprint import pprint
3Vì vậy, mã trên sẽ sử dụng giá trị mặc định của các trường ẩn [như mã thông báo CSRF] và nhắc người dùng cho các trường đầu vào khác [như tìm kiếm, email, văn bản và các trường khác]. Nó cũng sẽ nhắc người dùng chọn từ các tùy chọn
4 có sẵn.# initialize an HTTP session
session = HTMLSession[]
Hãy xem cách chúng ta có thể gửi nó dựa trên phương thức:
from bs4 import BeautifulSoup
from requests_html import HTMLSession
from pprint import pprint
4Tôi chỉ sử dụng
0 hoặc # initialize an HTTP session
session = HTMLSession[]
1 ở đây, nhưng bạn có thể mở rộng điều này cho các phương thức HTTP khác như # initialize an HTTP session
session = HTMLSession[]
7 và def get_all_forms[url]:
"""Returns all form tags found on a web page's `url` """
# GET request
res = session.get[url]
# for javascript driven website
# res.html.render[]
soup = BeautifulSoup[res.html.html, "html.parser"]
return soup.find_all["form"]
2 [sử dụng Phiên.put [] và Phiên.delete [] phương thức tương ứng].session.put[] and session.delete[] methods respectively].# initialize an HTTP session
session = HTMLSession[]
Được rồi, bây giờ chúng tôi có biến
9 có chứa phản hồi HTTP; Điều này sẽ chứa trang web mà máy chủ gửi sau khi gửi biểu mẫu; Hãy chắc chắn rằng nó đã hoạt động. Mã dưới đây chuẩn bị nội dung HTML của trang web để lưu nó trên máy tính cục bộ của chúng tôi:def get_all_forms[url]:
"""Returns all form tags found on a web page's `url` """
# GET request
res = session.get[url]
# for javascript driven website
# res.html.render[]
soup = BeautifulSoup[res.html.html, "html.parser"]
return soup.find_all["form"]
from bs4 import BeautifulSoup
from requests_html import HTMLSession
from pprint import pprint
5Tất cả những điều này đang làm là thay thế các URL tương đối [như/wiki/lập trình_langage] bằng các URL tuyệt đối [chẳng hạn như & nbsp; //www.wikipedia.org/wiki/programming_l Language] Tôi đã lưu tất cả nội dung vào tệp cục bộ
0, hãy mở nó trong trình duyệt của chúng tôi:/wiki/Programming_language] with absolute URLs [such as //www.wikipedia.org/wiki/Programming_language],
so we can adequately browse the page locally in our computer. I've saved all the content into a local file def get_form_details[form]:
"""Returns the HTML details of a form,
including action, method and list of form controls [inputs, etc]"""
details = {}
# get the form action [requested URL]
action = form.attrs.get["action"].lower[]
# get the form method [POST, GET, DELETE, etc]
# if not specified, GET is the default in HTML
method = form.attrs.get["method", "get"].lower[]
# get all form inputs
inputs = []
for input_tag in form.find_all["input"]:
# get type of input form control
input_type = input_tag.attrs.get["type", "text"]
# get name attribute
input_name = input_tag.attrs.get["name"]
# get the default value of that input tag
input_value =input_tag.attrs.get["value", ""]
# add everything to that list
inputs.append[{"type": input_type, "name": input_name, "value": input_value}]
0, let's open it in our browser:def get_form_details[form]:
"""Returns the HTML details of a form,
including action, method and list of form controls [inputs, etc]"""
details = {}
# get the form action [requested URL]
action = form.attrs.get["action"].lower[]
# get the form method [POST, GET, DELETE, etc]
# if not specified, GET is the default in HTML
method = form.attrs.get["method", "get"].lower[]
# get all form inputs
inputs = []
for input_tag in form.find_all["input"]:
# get type of input form control
input_type = input_tag.attrs.get["type", "text"]
# get name attribute
input_name = input_tag.attrs.get["name"]
# get the default value of that input tag
input_value =input_tag.attrs.get["value", ""]
# add everything to that list
inputs.append[{"type": input_type, "name": input_name, "value": input_value}]
from bs4 import BeautifulSoup
from requests_html import HTMLSession
from pprint import pprint
6Được rồi, mã được thực hiện. Đây là cách tôi thực hiện điều này:
from bs4 import BeautifulSoup
from requests_html import HTMLSession
from pprint import pprint
7Ban đầu, tập lệnh đã nhắc tôi chọn từ danh sách các biểu mẫu. Trong trường hợp của chúng tôi, chỉ có một hình thức. Sau đó, nó đã nhắc tôi cho tất cả các biểu mẫu không ẩn có sẵn, đó là trường
1 và def get_form_details[form]:
"""Returns the HTML details of a form,
including action, method and list of form controls [inputs, etc]"""
details = {}
# get the form action [requested URL]
action = form.attrs.get["action"].lower[]
# get the form method [POST, GET, DELETE, etc]
# if not specified, GET is the default in HTML
method = form.attrs.get["method", "get"].lower[]
# get all form inputs
inputs = []
for input_tag in form.find_all["input"]:
# get type of input form control
input_type = input_tag.attrs.get["type", "text"]
# get name attribute
input_name = input_tag.attrs.get["name"]
# get the default value of that input tag
input_value =input_tag.attrs.get["value", ""]
# add everything to that list
inputs.append[{"type": input_type, "name": input_name, "value": input_value}]
2.def get_form_details[form]:
"""Returns the HTML details of a form,
including action, method and list of form controls [inputs, etc]"""
details = {}
# get the form action [requested URL]
action = form.attrs.get["action"].lower[]
# get the form method [POST, GET, DELETE, etc]
# if not specified, GET is the default in HTML
method = form.attrs.get["method", "get"].lower[]
# get all form inputs
inputs = []
for input_tag in form.find_all["input"]:
# get type of input form control
input_type = input_tag.attrs.get["type", "text"]
# get name attribute
input_name = input_tag.attrs.get["name"]
# get the default value of that input tag
input_value =input_tag.attrs.get["value", ""]
# add everything to that list
inputs.append[{"type": input_type, "name": input_name, "value": input_value}]
Điều này về cơ bản giống như điền thủ công biểu mẫu trong trình duyệt web và chọn ngôn ngữ:
Sau khi tôi nhấn Enter trong thực thi mã của mình, điều này sẽ gửi biểu mẫu, lưu trang kết quả cục bộ và tự động mở nó trong trình duyệt web mặc định:
Đây là cách Python thấy kết quả, vì vậy chúng tôi đã gửi thành công mẫu tìm kiếm tự động và tải trang kết quả với sự trợ giúp của Python!
Sự kết luận
Được rồi, đó là nó. Trong hướng dẫn này, chúng tôi đã tìm kiếm Wikipedia. Tuy nhiên, như đã đề cập trước đó, bạn có thể sử dụng nó trên bất kỳ biểu mẫu nào bạn muốn, đặc biệt là cho các biểu mẫu đăng nhập, trong đó bạn có thể đăng nhập và tiếp tục trích xuất dữ liệu yêu cầu xác thực người dùng.
Xem cách bạn có thể mở rộng điều này. Chẳng hạn, bạn có thể cố gắng tạo một người gửi cho tất cả các biểu mẫu [vì chúng tôi chỉ sử dụng biểu mẫu đầu tiên ở đây] hoặc bạn có thể tạo một trình thu thập thông tin tinh vi để trích xuất tất cả các liên kết trang web và tìm thấy tất cả các hình thức của một trang web cụ thể. Tuy nhiên, hãy nhớ rằng một trang web có thể cấm địa chỉ IP của bạn nếu bạn yêu cầu nhiều trang trong một thời gian ngắn. Trong trường hợp đó, bạn có thể làm chậm trình thu thập dữ liệu của mình hoặc sử dụng proxy.
Ngoài ra, bạn có thể mở rộng mã này bằng cách tự động đăng nhập bằng Selenium. Kiểm tra & nbsp; hướng dẫn này về cách bạn có thể làm điều đó!
Bạn có thể nhận được mã hoàn chỉnh của hướng dẫn này ở đây.
Bạn muốn tìm hiểu thêm về việc quét web?
Cuối cùng, nếu bạn muốn đào sâu hơn vào việc quét web với các thư viện Python khác nhau, không chỉ Đẹp, các khóa học dưới đây chắc chắn sẽ có giá trị đối với bạn:
- Modern Web Scraping với Python bằng cách sử dụng selen selen.
- Quét web và các nguyên tắc cơ bản API trong Python.
Học thêm: Cách chuyển đổi các bảng HTML thành các tệp CSV trong Python. How to Convert HTML Tables into CSV Files in Python.
Hạnh phúc cào ♥
Xem đầy đủ mã