Sau bài viết trước về Python Web Scraping: Trích xuất tất cả câu hỏi từ một chủ đề trên Zhihu, tôi muốn nói rằng tôi đã chuyển sang một môi trường phát triển và thư viện công cụ mới. Hiện tại, tôi đang sử dụng:
Môi trường: Python 3.5
Yêu cầu HTTP: requests
Xử lý XML: BeautifulSoup + lxml
Sau khi có thể trích xuất các câu hỏi từ một chủ đề cụ thể, tôi bắt đầu tự hỏi làm thế nào để thu thập toàn bộ dữ liệu từ trang web Zhihu? Phương pháp truyền thống là bắt đầu từ một trang bất kỳ (thường là trang chủ), sau đó trích xuất các URL từ trang này và tiếp tục truy cập các trang khác dựa trên các URL đã tìm được. Tuy nhiên, đối với người mới bắt đầu, cách tiếp cận này khá phức tạp vì đòi hỏi phải xử lý nhiều vấn đề như phân tích URL, điều phối quá trình thu thập dữ liệu và loại bỏ trùng lặp.
Tôi không muốn ngay lập tức sử dụng Scrapy – một framework mạnh mẽ nhưng phức tạp dành cho scraping, vì vậy tôi quyết định tìm một phương pháp khác phù hợp hơn. Tôi nhận ra rằng cấu trúc của Zhihu rất rõ ràng 77win1 và nội dung được tổ chức theo thứ tự: Chủ đề → Câu hỏi → Đáp án → Bình luận. Vì vậy, tôi có thể tuân theo thứ tự này để thu thập dữ liệu, sau cùng là thông tin về người dùng.
Bước đầu tiên cần thiết là lấy danh sách tất cả các chủ đề. Tuy nhiên, tôi nhận thấy rằng trang chứa cấu trúc chủ đề yêu cầu đăng nhập để xem. Điều này dẫn đến bài viết này nhằm giải thích cách mô phỏng việc đăng nhập vào Zhihu.
Thu thập thông tin đăng nhập
Bằng cách sử dụng công cụ phát triển của Chrome, tôi đã kiểm tra thông tin đăng nhập của Zhihu như hình dưới đây:
!Trang đăng nhập Zhihu
Địa chỉ đăng nhập của Zhihu là ``, với phương thức gửi yêu cầu là POST
. Khi đăng nhập, bạn cần gửi năm dữ liệu sau:
_xsrf: Một giá trị kiểm tra dường như được tạo ngẫu nhiên, có thể tìm thấy trong mã nguồn HTML.
password: Mật khẩu tài [ty le chau a](/posts/bd3eda2408203db6/) khoản.
captcha: Mã xác thực hình ảnh.
remember_me: Giá trị boolean cho phép lưu phiên đăng nhập.
email: Địa chỉ email của tài khoản.
Trong số này, ba mục email
, password
và remember_me
khá đơn giản. Vấn đề chính nằm ở cách lấy giá trị _xsrf
và mã xác thực hình ảnh (captcha
).
Trong mã nguồn HTML của trang, đoạn mã sau đây chứa giá trị _xsrf
, có thể dễ dàng trích xuất bằng BeautifulSoup:
<input type="hidden" name="_xsrf" value="df557baede680642b1e1ab5974011246"/>
Về phần mã xác thực hình ảnh, tôi đã sao chép nó từ trang đăng nhập và lưu trữ dưới dạng tập tin cục bộ.
Trong chương trình, tôi cần tải xuống hình ảnh mã xác thực và yêu cầu người dùng nhập mã thủ công.
Mô phỏng đăng nhập vào Zhihu
Hiểu rõ quy trình đăng nhập và các thông tin cần thiết, bây giờ chúng ta có thể bắt đầu viết mã.
import requests
from bs4 import BeautifulSoup
import re
# Tạo một session để giữ thông tin đăng nhập
s = requests.Session()
# Thiết lập headers
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip,deflate",
"Accept-Language": "en-US,en;q=0.8,zh-TW;q=0.6,zh;q=0.4",
"Connection": "keep-alive",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36",
"Referer": ""
}
# Gửi yêu cầu GET để lấy trang đăng nhập
html = s.get('', headers=headers)
soup = BeautifulSoup(html.text, 'lxml')
# Tìm giá trị _xsrf
_xsrf = soup.find('input', {'type': 'hidden'})['value']
# Tải xuống hình ảnh captcha và lưu vào tệp cục bộ
captcha_url = ''
captcha = s.get(captcha_url, stream=True, headers=headers)
with open('captcha.gif', 'wb') as f:
for chunk in captcha.iter_content(10):
f.write(chunk)
f.close()
# Nhập mã captcha từ người dùng
print('Nhập mã captcha:', end=' ')
captcha_str = input()
# Chuẩn bị dữ liệu đăng nhập
data = {
'_xsrf': _xsrf,
'email': '123456789@qq.com', # Thay thế bằng địa chỉ email hợp lệ
'password': 'password', # Thay thế bằng mật khẩu hợp lệ
'remember_me': 'true',
'captcha': captcha_str
}
# Gửi yêu cầu POST để đăng nhập
r = s.post(url='', data=data, headers=headers)
# Kiểm tra trạng thái đăng nhập
print('Trạng thái đăng nhập:', r.json())
Khi chạy chương trình với email và mật khẩu đúng, hệ thống sẽ nhắc nhở bạn nhập mã captcha dựa trên hình ảnh đã lưu. Kết quả cuối cùng có thể trông như sau:
Nhập mã captcha: hrfv
Trạng thái đăng nhập: {'r': 0, 'msg': 'Đăng nhập thành công'}
Thành công!
BƯỚC TIẾP THEO: Thu thập cấu trúc chủ đề của Zhihu
Sửa đổi lần cuối vào 2025-02-24