Làm cách nào để bắt đầu quét web?

Quét web là quá trình tự động trích xuất dữ liệu cụ thể từ internet. Nó có nhiều trường hợp sử dụng, chẳng hạn như lấy dữ liệu cho dự án máy học, tạo công cụ so sánh giá hoặc bất kỳ ý tưởng sáng tạo nào khác yêu cầu lượng dữ liệu khổng lồ

Mặc dù về mặt lý thuyết, bạn có thể thực hiện trích xuất dữ liệu theo cách thủ công, nhưng nội dung rộng lớn của internet khiến phương pháp này không thực tế trong nhiều trường hợp. Vì vậy, biết cách xây dựng một công cụ quét web có thể hữu ích

Mục đích của bài viết này là hướng dẫn bạn cách tạo một công cụ quét web bằng Python. Bạn sẽ tìm hiểu cách kiểm tra trang web để chuẩn bị quét, trích xuất dữ liệu cụ thể bằng BeautifulSoup, đợi kết xuất JavaScript bằng Selenium và lưu mọi thứ trong tệp JSON hoặc CSV mới

Nhưng trước tiên, tôi nên cảnh báo bạn về tính hợp pháp của việc quét web. Mặc dù hành động thu thập dữ liệu là hợp pháp nhưng dữ liệu bạn có thể trích xuất có thể là bất hợp pháp khi sử dụng. Hãy chắc chắn rằng bạn không gây rối với bất kỳ

  • Nội dung có bản quyền – vì nó là tài sản trí tuệ của ai đó, nó được luật pháp bảo vệ và bạn không thể sử dụng lại nó
  • Dữ liệu cá nhân – nếu thông tin bạn thu thập có thể được sử dụng để nhận dạng một người thì đó được coi là dữ liệu cá nhân và đối với công dân EU, thông tin đó được bảo vệ theo GDPR. Trừ khi bạn có lý do hợp pháp để lưu trữ dữ liệu đó, tốt hơn hết là bỏ qua hoàn toàn

Nói chung, bạn phải luôn đọc các điều khoản và điều kiện của trang web trước khi cạo để đảm bảo rằng bạn không vi phạm chính sách của họ. Nếu bạn không chắc chắn về cách tiến hành, hãy liên hệ với chủ sở hữu trang web và yêu cầu sự đồng ý

Bạn sẽ cần gì cho cái cạp của mình?

Để bắt đầu xây dựng trình quét web của riêng bạn, trước tiên bạn cần cài đặt Python trên máy của mình. Ubuntu 20. 04 và các phiên bản Linux khác được cài đặt sẵn Python 3

Để kiểm tra xem bạn đã cài đặt Python trên thiết bị của mình chưa, hãy chạy lệnh sau

python3 -v

Nếu bạn đã cài đặt Python, bạn sẽ nhận được kết quả như thế này

Python 3.8.2

Ngoài ra, đối với trình quét web của chúng tôi, chúng tôi sẽ sử dụng các gói Python BeautifulSoup [để chọn dữ liệu cụ thể] và Selenium [để hiển thị nội dung được tải động]. Để cài đặt chúng, chỉ cần chạy các lệnh này

pip3 install beautifulsoup4

pip3 install selenium

Bước cuối cùng là đảm bảo rằng bạn đã cài đặt Google Chrome và Trình điều khiển Chrome trên máy của mình. Những thứ này sẽ cần thiết nếu chúng ta muốn sử dụng Selenium để cạo nội dung được tải động

Cách kiểm tra trang

Bây giờ bạn đã cài đặt xong mọi thứ, đã đến lúc bắt đầu dự án cạo của chúng tôi một cách nghiêm túc

Bạn nên chọn trang web bạn muốn cạo dựa trên nhu cầu của bạn. Hãy nhớ rằng mỗi trang web có cấu trúc nội dung khác nhau, vì vậy bạn sẽ cần điều chỉnh những gì bạn học được ở đây khi bạn bắt đầu tự tìm hiểu. Mỗi trang web sẽ yêu cầu những thay đổi nhỏ đối với mã

Đối với bài viết này, tôi quyết định thu thập thông tin về mười bộ phim đầu tiên trong danh sách 250 phim hàng đầu từ IMDb. https. //www. imdb. com/chart/top/

Đầu tiên, chúng tôi sẽ lấy tiêu đề, sau đó chúng tôi sẽ đi sâu hơn bằng cách trích xuất thông tin từ trang của mỗi bộ phim. Một số dữ liệu sẽ yêu cầu kết xuất JavaScript

Để bắt đầu hiểu cấu trúc của nội dung, bạn nên nhấp chuột phải vào tiêu đề đầu tiên trong danh sách, sau đó chọn “Kiểm tra phần tử”

By pressing CTRL+F and searching in the HTML code structure, you will see that there is only one

tag on the page. This is useful as it gives us information about how we can access the data.

Bộ chọn HTML sẽ cung cấp cho chúng tôi tất cả các tiêu đề từ trang là

Python 3.8.2
4. Đó là bởi vì tất cả các tiêu đề đều nằm trong một neo bên trong một ô của bảng với lớp “titleColumn”

Sử dụng bộ chọn CSS này và lấy văn bản bên trong của mỗi neo sẽ cung cấp cho chúng tôi các tiêu đề mà chúng tôi cần. Bạn có thể mô phỏng điều đó trong bảng điều khiển trình duyệt từ cửa sổ mới mà bạn vừa mở và bằng cách sử dụng dòng JavaScript

document.querySelectorAll["table tbody tr td.titleColumn a"][0].innerText

Bạn sẽ thấy một cái gì đó như thế này

Bây giờ chúng ta có bộ chọn này, chúng ta có thể bắt đầu viết mã Python và trích xuất thông tin chúng ta cần

Cách sử dụng BeautifulSoup để trích xuất nội dung được tải tĩnh

Tiêu đề phim từ danh sách của chúng tôi là nội dung tĩnh. Đó là bởi vì nếu bạn nhìn vào nguồn trang [CTRL+U trên trang hoặc nhấp chuột phải rồi chọn Xem nguồn trang], bạn sẽ thấy rằng các tiêu đề đã có sẵn ở đó

Nội dung tĩnh thường dễ cạo hơn vì nó không yêu cầu kết xuất JavaScript. Để trích xuất mười tiêu đề đầu tiên trong danh sách, chúng tôi sẽ sử dụng BeautifulSoup để lấy nội dung và sau đó in nó ra đầu ra của trình cạp của chúng tôi

import requests
from bs4 import BeautifulSoup
 
page = requests.get['//www.imdb.com/chart/top/'] # Getting page HTML through request
soup = BeautifulSoup[page.content, 'html.parser'] # Parsing content using beautifulsoup
 
links = soup.select["table tbody tr td.titleColumn a"] # Selecting all of the anchors with titles
first10 = links[:10] # Keep only the first 10 anchors
for anchor in first10:
    print[anchor.text] # Display the innerText of each anchor

Đoạn mã trên sử dụng bộ chọn mà chúng ta đã thấy ở bước đầu tiên để trích xuất các neo tiêu đề phim từ trang. Sau đó, nó lặp qua mười phần đầu tiên và hiển thị nội dung bên trong của mỗi phần

Đầu ra sẽ trông như thế này

Cách trích xuất nội dung được tải động

Khi công nghệ tiên tiến, các trang web bắt đầu tải nội dung của họ một cách linh hoạt. Điều này cải thiện hiệu suất của trang, trải nghiệm của người dùng và thậm chí loại bỏ rào cản bổ sung đối với người dọn dẹp

Tuy nhiên, điều này làm phức tạp mọi thứ vì HTML được truy xuất từ ​​một yêu cầu đơn giản sẽ không chứa nội dung động. May mắn thay, với Selenium, chúng ta có thể mô phỏng một yêu cầu trong trình duyệt và đợi nội dung động được hiển thị

Cách sử dụng Selenium cho các yêu cầu

Bạn sẽ cần biết vị trí của chromedriver của mình. Đoạn mã sau giống với đoạn mã được trình bày trong bước thứ hai, nhưng lần này chúng tôi đang sử dụng Selenium để thực hiện yêu cầu. Chúng tôi vẫn sẽ phân tích cú pháp nội dung của trang bằng BeautifulSoup, như chúng tôi đã làm trước đây

from bs4 import BeautifulSoup
from selenium import webdriver
 
option = webdriver.ChromeOptions[]
# I use the following options as my machine is a window subsystem linux. 
# I recommend to use the headless option at least, out of the 3
option.add_argument['--headless']
option.add_argument['--no-sandbox']
option.add_argument['--disable-dev-sh-usage']
# Replace YOUR-PATH-TO-CHROMEDRIVER with your chromedriver location
driver = webdriver.Chrome['YOUR-PATH-TO-CHROMEDRIVER', options=option]
 
driver.get['//www.imdb.com/chart/top/'] # Getting page HTML through request
soup = BeautifulSoup[driver.page_source, 'html.parser'] # Parsing content using beautifulsoup. Notice driver.page_source instead of page.content
 
links = soup.select["table tbody tr td.titleColumn a"] # Selecting all of the anchors with titles
first10 = links[:10] # Keep only the first 10 anchors
for anchor in first10:
    print[anchor.text] # Display the innerText of each anchor

Đừng quên thay thế “YOUR-PATH-TO-CHROMEDRIVER” bằng vị trí mà bạn đã giải nén chromedriver. Ngoài ra, bạn nên lưu ý rằng thay vì

Python 3.8.2
5, khi chúng tôi tạo đối tượng BeautifulSoup, chúng tôi hiện đang sử dụng
Python 3.8.2
6, cung cấp nội dung HTML của trang

Cách trích xuất nội dung được tải tĩnh bằng Selenium

Sử dụng mã ở trên, bây giờ chúng ta có thể truy cập từng trang phim bằng cách gọi phương thức nhấp chuột trên mỗi neo

first_link = driver.find_elements_by_css_selector['table tbody tr td.titleColumn a'][0]
first_link.click[]

Điều này sẽ mô phỏng một lần nhấp vào liên kết của bộ phim đầu tiên. Tuy nhiên, trong trường hợp này, tôi khuyên bạn nên tiếp tục sử dụng

Python 3.8.2
7. Điều này là do bạn sẽ không còn có thể sử dụng phương pháp
Python 3.8.2
8 sau khi bạn truy cập một trang khác vì trang mới không có liên kết đến chín bộ phim khác

Do đó, sau khi nhấp vào tiêu đề đầu tiên trong danh sách, bạn cần quay lại trang đầu tiên, sau đó nhấp vào tiêu đề thứ hai, v.v. Đây là một sự lãng phí hiệu suất và thời gian. Thay vào đó, chúng tôi sẽ chỉ sử dụng các liên kết được trích xuất và truy cập từng liên kết một

Đối với “The Shawshank Redemption”, trang phim sẽ là https. //www. imdb. com/title/tt0111161/. Chúng tôi sẽ trích xuất năm và thời lượng của bộ phim từ trang, nhưng lần này chúng tôi sẽ sử dụng các chức năng của Selenium thay vì BeautifulSoup làm ví dụ. Trong thực tế, bạn có thể sử dụng một trong hai, vì vậy hãy chọn mục yêu thích của bạn

Để truy xuất năm và thời lượng của bộ phim, bạn nên lặp lại bước đầu tiên mà chúng tôi đã thực hiện ở đây trên trang của bộ phim

Bạn sẽ nhận thấy rằng bạn có thể tìm thấy tất cả thông tin trong phần tử đầu tiên với lớp

Python 3.8.2
9 [". ipc-inline-list"] và tất cả các thành phần của danh sách đều chứa thuộc tính
pip3 install beautifulsoup4
0 với giá trị
pip3 install beautifulsoup4
1 [bộ chọn
pip3 install beautifulsoup4
2]

from bs4 import BeautifulSoup
from selenium import webdriver
 
option = webdriver.ChromeOptions[]
# I use the following options as my machine is a window subsystem linux. 
# I recommend to use the headless option at least, out of the 3
option.add_argument['--headless']
option.add_argument['--no-sandbox']
option.add_argument['--disable-dev-sh-usage']
# Replace YOUR-PATH-TO-CHROMEDRIVER with your chromedriver location
driver = webdriver.Chrome['YOUR-PATH-TO-CHROMEDRIVER', options=option]
 
page = driver.get['//www.imdb.com/chart/top/'] # Getting page HTML through request
soup = BeautifulSoup[driver.page_source, 'html.parser'] # Parsing content using beautifulsoup
 
totalScrapedInfo = [] # In this list we will save all the information we scrape
links = soup.select["table tbody tr td.titleColumn a"] # Selecting all of the anchors with titles
first10 = links[:10] # Keep only the first 10 anchors
for anchor in first10:
    driver.get['//www.imdb.com/' + anchor['href']] # Access the movie’s page
    infolist = driver.find_elements_by_css_selector['.ipc-inline-list'][0] # Find the first element with class ‘ipc-inline-list’
    informations = infolist.find_elements_by_css_selector["[role='presentation']"] # Find all elements with role=’presentation’ from the first element with class ‘ipc-inline-list’
    scrapedInfo = {
        "title": anchor.text,
        "year": informations[0].text,
        "duration": informations[2].text,
    } # Save all the scraped information in a dictionary
    totalScrapedInfo.append[scrapedInfo] # Append the dictionary to the totalScrapedInformation list
    
print[totalScrapedInfo] # Display the list with all the information we scraped

Cách trích xuất nội dung được tải động bằng Selenium

Bước quan trọng tiếp theo trong việc quét web là trích xuất nội dung được tải động. Bạn có thể tìm thấy nội dung như vậy trên từng trang của phim [chẳng hạn như https. //www. imdb. com/title/tt0111161/] trong phần Danh sách biên tập

Nếu bạn xem bằng cách sử dụng kiểm tra trên trang, bạn sẽ thấy rằng bạn có thể tìm thấy phần đó dưới dạng một thành phần có thuộc tính

pip3 install beautifulsoup4
3 được đặt là
pip3 install beautifulsoup4
4. Nhưng nếu bạn tìm trong nguồn trang, bạn sẽ không tìm thấy giá trị thuộc tính này ở bất kỳ đâu. Đó là vì phần Danh sách biên tập được IMDB tải động

Trong ví dụ sau, chúng tôi sẽ loại bỏ danh sách biên tập của từng bộ phim và thêm nó vào kết quả hiện tại của chúng tôi về tổng thông tin đã loại bỏ

Để làm điều đó, chúng tôi sẽ nhập thêm một vài gói để có thể chờ tải nội dung động của chúng tôi

from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
 
option = webdriver.ChromeOptions[]
# I use the following options as my machine is a window subsystem linux. 
# I recommend to use the headless option at least, out of the 3
option.add_argument['--headless']
option.add_argument['--no-sandbox']
option.add_argument['--disable-dev-sh-usage']
# Replace YOUR-PATH-TO-CHROMEDRIVER with your chromedriver location
driver = webdriver.Chrome['YOUR-PATH-TO-CHROMEDRIVER', options=option]
 
page = driver.get['//www.imdb.com/chart/top/'] # Getting page HTML through request
soup = BeautifulSoup[driver.page_source, 'html.parser'] # Parsing content using beautifulsoup
 
totalScrapedInfo = [] # In this list we will save all the information we scrape
links = soup.select["table tbody tr td.titleColumn a"] # Selecting all of the anchors with titles
first10 = links[:10] # Keep only the first 10 anchors
for anchor in first10:
    driver.get['//www.imdb.com/' + anchor['href']] # Access the movie’s page 
    infolist = driver.find_elements_by_css_selector['.ipc-inline-list'][0] # Find the first element with class ‘ipc-inline-list’
    informations = infolist.find_elements_by_css_selector["[role='presentation']"] # Find all elements with role=’presentation’ from the first element with class ‘ipc-inline-list’
    scrapedInfo = {
        "title": anchor.text,
        "year": informations[0].text,
        "duration": informations[2].text,
    } # Save all the scraped information in a dictionary
    WebDriverWait[driver, 5].until[EC.visibility_of_element_located[[By.CSS_SELECTOR, "[data-testid='firstListCardGroup-editorial']"]]]  # We are waiting for 5 seconds for our element with the attribute data-testid set as `firstListCardGroup-editorial`
    listElements = driver.find_elements_by_css_selector["[data-testid='firstListCardGroup-editorial'] .listName"] # Extracting the editorial lists elements
    listNames = [] # Creating an empty list and then appending only the elements texts
    for el in listElements:
        listNames.append[el.text]
    scrapedInfo['editorial-list'] = listNames # Adding the editorial list names to our scrapedInfo dictionary
    totalScrapedInfo.append[scrapedInfo] # Append the dictionary to the totalScrapedInformation list
    
print[totalScrapedInfo] # Display the list with all the information we scraped

Đối với ví dụ trước, bạn sẽ nhận được đầu ra sau

Cách lưu nội dung đã cạo

Bây giờ chúng tôi có tất cả dữ liệu chúng tôi muốn, chúng tôi có thể lưu nó dưới dạng. json hoặc một. csv để dễ đọc hơn

Để làm điều đó, chúng tôi sẽ chỉ sử dụng các gói JSON và CSV từ Python và ghi nội dung của chúng tôi vào các tệp mới

Python 3.8.2
0

Mẹo và thủ thuật cạo

Mặc dù hướng dẫn của chúng tôi cho đến nay đã đủ nâng cao để xử lý các kịch bản kết xuất JavaScript, nhưng vẫn còn nhiều điều cần khám phá trong Selenium

Trong phần này, tôi sẽ chia sẻ một số mẹo và thủ thuật có thể hữu ích

1. Thời gian yêu cầu của bạn

Nếu bạn spam một máy chủ với hàng trăm yêu cầu trong một thời gian ngắn, rất có thể đến một lúc nào đó mã captcha sẽ xuất hiện hoặc thậm chí IP của bạn có thể bị chặn. Thật không may, không có cách giải quyết nào trong Python để tránh điều đó

Do đó, bạn nên đặt một số khoảng thời gian chờ giữa mỗi yêu cầu để lưu lượng truy cập trông tự nhiên hơn

Python 3.8.2
1

2. xử lý lỗi

Vì các trang web luôn động và chúng có thể thay đổi cấu trúc bất kỳ lúc nào nên việc xử lý lỗi có thể hữu ích nếu bạn thường xuyên sử dụng cùng một công cụ quét web

Python 3.8.2
2

Cú pháp thử và lỗi có thể hữu ích khi bạn đang đợi một phần tử, giải nén phần tử đó hoặc ngay cả khi bạn chỉ thực hiện yêu cầu

3. Chụp ảnh màn hình

Nếu bạn cần lấy ảnh chụp màn hình của trang web mà bạn đang quét bất cứ lúc nào, bạn có thể sử dụng

Python 3.8.2
3

Điều này có thể giúp gỡ lỗi khi bạn đang làm việc với nội dung được tải động

4. Đọc tài liệu

Cuối cùng nhưng không kém phần quan trọng, đừng quên đọc tài liệu từ Selenium. Thư viện này chứa thông tin về cách thực hiện hầu hết các tác vụ bạn có thể thực hiện trong trình duyệt

Sử dụng Selenium, bạn có thể điền vào biểu mẫu, nhấn nút, trả lời tin nhắn bật lên và làm nhiều điều thú vị khác

Nếu bạn đang đối mặt với một vấn đề mới, tài liệu của họ có thể là người bạn tốt nhất của bạn

Suy nghĩ cuối cùng

Mục đích của bài viết này là cung cấp cho bạn phần giới thiệu nâng cao về quét web bằng Python với Selenium và BeautifulSoup. Mặc dù vẫn còn nhiều tính năng từ cả hai công nghệ để khám phá, nhưng giờ đây bạn đã có cơ sở vững chắc về cách bắt đầu tìm hiểu

Đôi khi, việc quét web có thể rất khó khăn, vì các trang web bắt đầu ngày càng có nhiều chướng ngại vật cản trở nhà phát triển. Một số trở ngại này có thể là mã Captcha, khối IP hoặc nội dung động. Vượt qua chúng chỉ bằng Python và Selenium có thể khó hoặc thậm chí là không thể

Vì vậy, tôi cũng sẽ cung cấp cho bạn một giải pháp thay thế. Hãy thử sử dụng API quét web để giải quyết tất cả những thách thức đó cho bạn. Nó cũng sử dụng proxy luân phiên để bạn không phải lo lắng về việc thêm thời gian chờ giữa các yêu cầu. Chỉ cần nhớ luôn kiểm tra xem dữ liệu bạn muốn có thể được trích xuất và sử dụng hợp pháp hay không

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

Sorin-Gabriel Marica

Tôi là một nhà phát triển web đam mê với nhiều tham vọng lớn, hiện đang làm việc tại JECO Technology trong các dự án như WebScrapingAPI

Nếu bài viết này hữu ích, hãy tweet nó

Học cách viết mã miễn phí. Chương trình giảng dạy mã nguồn mở của freeCodeCamp đã giúp hơn 40.000 người có được việc làm với tư cách là nhà phát triển. Bắt đầu

Quét web có dễ học không?

Dễ dàng quét web. Bất kỳ ai thậm chí không có bất kỳ kiến ​​thức nào về mã hóa đều có thể cạo dữ liệu nếu họ được cung cấp công cụ phù hợp. Lập trình không phải là lý do khiến bạn không thu thập dữ liệu bạn cần. Có nhiều công cụ khác nhau, chẳng hạn như Octoparse, được thiết kế để giúp những người không phải là lập trình viên tìm kiếm dữ liệu liên quan trên các trang web.

HTML có cần thiết để quét web không?

Quét web . Đôi khi sẽ thật tuyệt nếu có được một số dữ liệu từ chúng và bảo toàn cấu trúc trong khi chúng tôi đang ở đó. Các trang web không phải lúc nào cũng cung cấp dữ liệu của họ ở các định dạng thoải mái như CSV hoặc JSON. Web sites are written using HTML, which means that each web page is a structured document. Sometimes it would be great to obtain some data from them and preserve the structure while we're at it. Web sites don't always provide their data in comfortable formats such as CSV or JSON.

Ngôn ngữ lập trình nào được sử dụng để quét web?

Python được coi là ngôn ngữ lập trình được sử dụng phổ biến nhất để quét web. Ngẫu nhiên, nó cũng là ngôn ngữ lập trình hàng đầu cho năm 2021 theo IEEE Spectrum. Ngôn ngữ hướng đối tượng này đi kèm với một nhóm thư viện khổng lồ, bao gồm các mô-đun dành cho máy học.

Chủ Đề