Làm thế nào để quét một trang web javascript bằng Python?

Sep 06 2020

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

2 politicalscientist Sep 06 2020 at 15:38

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()
2 Noname Sep 06 2020 at 15:39

Có nhiều cách khác nhau để thu thập nội dung của một trang web có chứa Javascript.

  1. Sử dụng seleniumvới trình điều khiển web Firefox
  2. Sử dụng trình duyệt không đầu với phantomJS
  3. 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

2 MananGajjar Sep 06 2020 at 16:04

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 :)

2 DemianWolf Sep 06 2020 at 16:00

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:

  1. 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):
  1. 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(...).

  2. 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ụng pprintthay vì in đơn giản. Lưu ý bạn phải làm from 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 .