Làm thế nào để quét một trang web javascript bằng Python?
Tôi đang cố gắng tìm kiếm một trang web. Tôi đã thử sử dụng hai phương pháp nhưng cả hai đều không cung cấp cho tôi mã nguồn trang web đầy đủ mà tôi đang tìm kiếm. Tôi đang cố gắng loại bỏ các tiêu đề tin tức từ URL trang web được cung cấp bên dưới.
URL: "https://www.todayonline.com/"
Đây là hai phương pháp tôi đã thử nhưng không thành công.
Phương pháp 1: Súp đẹp mắt
tdy_url = "https://www.todayonline.com/"
page = requests.get(tdy_url).text
soup = BeautifulSoup(page)
soup # Returns me a HTML with javascript text
soup.find_all('h3')
### Returns me empty list []
Phương pháp 2: Selenium + BeautifulSoup
tdy_url = "https://www.todayonline.com/"
options = Options()
options.headless = True
driver = webdriver.Chrome("chromedriver",options=options)
driver.get(tdy_url)
time.sleep(10)
html = driver.page_source
soup = BeautifulSoup(html)
soup.find_all('h3')
### Returns me only less than 1/4 of the 'h3' tags found in the original page source
Hãy giúp tôi. Tôi đã thử tìm kiếm các trang web tin tức khác và nó dễ dàng hơn nhiều. Cảm ơn bạn.
Trả lời
Bạn có thể truy cập dữ liệu qua API (kiểm tra tab Mạng):
Ví dụ,
import requests
url = "https://www.todayonline.com/api/v3/news_feed/7"
data = requests.get(url).json()
Có nhiều cách khác nhau để thu thập nội dung của một trang web có chứa Javascript.
- Sử dụng
seleniumvới trình điều khiển web Firefox - Sử dụng trình duyệt không đầu với
phantomJS - Thực hiện lệnh gọi API bằng ứng dụng khách REST hoặc
requeststhư viện python
Bạn phải nghiên cứu trước
Tôi sẽ gợi ý cho bạn cách tiếp cận khá đơn giản,
import requests
from bs4 import BeautifulSoup as bs
page = requests.get('https://www.todayonline.com/googlenews.xml').content
soup = bs(page)
news = [i.text for i in soup.find_all('news:title')]
print(news)
đầu ra
['DBS named world’s best bank by New York-based financial publication',
'Russia has very serious questions to answer on Navalny - UK',
"Exclusive: 90% of China's Sinovac employees, families took coronavirus vaccine - CEO",
'Three militants killed after fatal attack on policeman in Tunisia',
.....]
Ngoài ra, bạn có thể kiểm tra trang XML để biết thêm thông tin nếu cần.
PS Luôn kiểm tra sự tuân thủ trước khi loại bỏ bất kỳ trang web nào :)
Dữ liệu tin tức trên trang web mà bạn đang cố gắng thu thập được tìm nạp từ máy chủ bằng JavaScript (đây được gọi là XHR - XMLHttpRequest ). Nó đang diễn ra động, trong khi trang đang tải hoặc đang được cuộn. vì vậy dữ liệu này không được trả về bên trong trang do máy chủ trả về.
Trong ví dụ đầu tiên, bạn chỉ nhận được trang do máy chủ trả về - không có tin tức, nhưng với JS được cho là lấy chúng. Cả yêu cầu và BeautifulSoup đều không thể thực thi JS.
Tuy nhiên, bạn có thể cố gắng tái tạo các yêu cầu nhận được tiêu đề tin tức từ máy chủ với các yêu cầu Python. Thực hiện các bước sau:
- Mở DevTools của trình duyệt của bạn (thông thường bạn phải nhấn F12hoặc Ctrl+ Shit+ Icho điều đó) và xem xét các yêu cầu nhận tiêu đề tin tức từ máy chủ. Đôi khi, nó thậm chí còn dễ dàng hơn việc tìm kiếm trên web với BeautifulSoup. Đây là ảnh chụp màn hình (Firefox):
Sao chép liên kết yêu cầu (nhấp chuột phải -> Sao chép -> Sao chép liên kết) và chuyển nó đến
requests.get(...).Nhận
.json()yêu cầu. Nó sẽ trả về một mệnh lệnh dễ làm việc. Để hiểu rõ hơn về cấu trúc của dict, tôi khuyên bạn nên sử dụngpprintthay vì in đơn giản. Lưu ý bạn phải làmfrom pprint import pprinttrước khi sử dụng nó.
Đây là một ví dụ về mã lấy tiêu đề từ tin tức chính trên trang:
import requests
nodes = requests.get("https://www.todayonline.com/api/v3/news_feed/7")\
.json()["nodes"]
for node in nodes:
print(node["node"]["title"])
Nếu bạn muốn loại bỏ một nhóm tin tức dưới chú thích, bạn cần thay đổi số sau news_feed/trong URL yêu cầu (để lấy nó, bạn chỉ cần lọc các yêu cầu theo "news_feed" trong DevTools và cuộn trang tin tức xuống).
Đôi khi các trang web có bảo vệ chống lại bot (mặc dù trang web bạn đang cố gắng gỡ bỏ thì không). Trong những trường hợp như vậy, bạn cũng có thể cần thực hiện các bước này .