Hướng dẫn get website content python

Hướng dẫn cách lấy dữ liệu từ web bằng python dễ hiểu, sử dụng module request và tạo hàm để tái sử dụng khi cần

Hiện nay hầu hết các doanh nghiệp, tổ chức kinh doanh đều có nhiều hoạt động mạnh mẽ trên các nền tảng website và điều đó dẫn tới việc một khối lượng rất lớn dữ liệu được liên tục tạo ra trên nền tảng website. Để phục vụ việc học tập nghiên cứu cũng như phân tích dữ liệu cho quá trình đưa ra các quyết định kinh doanh, bạn có thể lấy dữ liệu từ web bằng python theo các bước dưới đây:

Bước 1: Cài đặt module (hướng dẫn cho cmd Window)

Để lấy dữ liệu từ web bằng python, đầu tiên bạn cần cài đặt Requests:

pip install requests (hoặc python –m pip install requests)​

Cài đặt Pilow:

pip install Pillow (hoặc python –m pip install Pillow)​

*Lưu ý: Nếu bạn đang dùng PIP cũ thì hãy update lên pip mới trước khi cài Pillow với cú pháp như sau nhé: Update PIP:

pip install -–upgrade pip (hoặc python –m pip install -–upgrade pip)
 

Bước 2: Crawl dữ liệu từ danh sách tin tức mới nhất

Lấy dữ liệu

Hiểu một cách đơn giản thì Module Request dùng để gửi HTTP request, điều này cũng giống như thao tác bạn thường làm khi tìm kiếm thứ gì đó trên mạng: Vào trình duyệt, gõ vào thanh tìm kiếm “mcivietnam” và enter, bạn sẽ nhận được giao diện của trang web MCI hoặc một dạng dữ liệu khác trả về. Để lấy được dữ liệu trả về chúng ta phải sử dụng một module để hỗ trợ và Request sẽ giúp bạn thực hiện việc đó.

requests.method(url, params, data, json, headers, cookies, files, auth, timeout, allow_redirects, proxies, verify, stream, cert)

Đoạn code này có vẻ khá phức tạp đúng không? Thực ra thì chúng ta không cần nhiều tham số đến vậy, bạn có thể sửa lại theo cách này để đoạn mã nhìn “đẹp” hơn:

import requests

response = requests.get("https://tuoitre.vn/tin-moi-nhat.htm")

print(response)

Những, bạn sẽ nhận được kết quả trả về như thế này:

Đây không phải là dữ liệu mà chúng ta cần, vì vậy, phải thêm một vài thuộc tính nữa để lấy dữ liệu từ web như mong muốn của chúng ta:

print(response.content)

Đây là kết quả trả về:

\r\n    \r\n    



Tin m\xe1\xbb\x9bi nh\xe1\xba\xa5t - Tu\xe1\xbb\x95i tr\xe1\xba\xbb Onlinecontent="Tin m\xe1\xbb\x9bi nh\xe1\xba\xa5t - Tu\xe1\xbb\x95i tr\xe1\xba\xbb Online" />content="Tin m\xe1\xbb\x9bi nh\xe1\xba\xa5t - Tu\xe1\xbb\x95i tr\xe1\xba\xbb Online" />content="" />content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=1" />

…(còn nữa>…

Tách dữ liệu crawl được từ web

Sau khi đã lấy được dữ liệu, việc tiếp theo cần làm là phải tách các dữ liệu ra thành dạng cây để thuận tiện hơn cho quá trình truy xuất dữ liệu. Các phổ biến là dùng module BeautifulSoup4. Cú pháp cài đặt module:

pip install beautifulsoup4 (hoặc python –m pip install beautifulsoup4

Sau đó, BeautifulSoup4 sẽ giúp bạn phân tích dữ liệu HTML, XML thành dạng cây với cú pháp như sau:

import requests

from bs4 import BeautifulSoup
response = requests.get("https://tuoitre.vn/tin-moi-nhat.htm")

soup = BeautifulSoup(response.content, "html.parser")

print(soup)

Phân tích dữ liệu

Sau khi đã hoàn thành, bước tiếp theo bạn cần làm là phân tích xem dữ liệu đang cần có thể lấy được ở đâu. Ví dụ bạn cần lấy chi tiết về một bài viết cụ thể, bạn cần biết liên kết để truy cập đến bài viết đó. Bạn có thể tìm kiếm thông tin đó bằng cách ấn F12 và tìm xem link bài báo ở đâu. Ví dụ chúng ta tìm thấy link bài báo ở trong thẻ , nằm trong thẻ h3 và có class là “title-news”. Vậy chúng ra cần phải lọc tất cả thẻ h3 có class “title-news” và lấy thẻ a trong đó, đoạn mã cần thiết được xây dựng là:

titles = soup.findAll('h3', class_='title-news')

print(titles)

Kết quả sẽ trả về cho chúng ta một mảng các thẻ h3 là tiêu đề của các bài báo. Tiếp theo chúng ta cần lấy link của các bài viết đó:

links = [link.find('a').attrs["href"] for link in titles]

print(links)

Kết quả trả về:

['/moi-cac-truong-tham-gia-cam-nang-tuyen-sinh-dh-cd-hau-covid-19-tang-thi-sinh-20200605093106804.htm', 
'/truong-tre-vao-top-10-cong-bo-quoc-te-va-nghi-van-mua-bai-bao-khoa-hoc-2020060509193892.htm',
'/nghi-si-9-nuoc-lap-lien-minh-dua-ra-lap-truong-cung-ran-hon-voi-trung-quoc-20200605084031973.htm',
'/mo-tinh-xuat-huyet-nao-20200605092647937.htm',…]

Lấy dữ liệu chi tiết của từng bài

Ở bước trước, chúng ta đã có được danh sách các thẻ h3 là tiêu đề của các bài báo, giờ chúng ta cần truy cập vào từng bài viết, lấy 1 ảnh đại diện và 1 đoạn trích trong bài viết đó, đoạn code được thực hiện như sau:

for link in links:

    news = requests.get("https://tuoitre.vn" + link)

    soup = BeautifulSoup(news.content, "html.parser")

    title = soup.find("h2", class_="article-title").text

    abstract = soup.find("h2", class_="sapo").text

    body = soup.find("div", id="main-detail-body")

    content = body.findChildren("p", recursive=False)[0].text +      body.findChildren("p", recursive=False)[1].text

    image = body.find("img").attrs["src"]

    print("Tiêu đề: " + title)

    print("Mô tả: " + abstract)

    print("Nội dung: " + content)

    print("Ảnh minh họa: " + image)

    print("_________________________________________________________________________")

Bingo, vậy là bạn đã hoàn thành xong phần crawl dữ liệu từ web bằng python rồi. Chúng tôi sẽ giải thích thêm một chút về các đoạn code: Đầu tiên chúng ta sử dụng một vòng for-loop để duyệt qua tất cả các link và sau đó truy cập vào các link đó, lưu ý do href của thẻ a không có link gốc (dạng “/router-ne”) nên chúng ta cần chèn thêm BASE URL vào:

requests.get("https://tuoitre.vn" + link)

Ở bước lấy tiêu đề, đoạn tóm tắt và ảnh đại diện. Bạn bật f12 lên tìm hiểu. Còn phần content mình cần tìm 2 thẻ p con chỉ dưới

một cấp nên ta sẽ có tham số recursive như sau:

body.findChildren("p", recursive=False)

Tạo hàm để tái sử dụng trong python

Sau khi hoàn thành các bước, bạn có thể tạo một hàm trong python với tên gọi Crawnewsdata() để thuận tiện sử dụng cho những lần sau, hàm này sẽ nhận vào url gốc, url đến nơi lấy bài và trả về một list các bài viết gồm tiêu đề, đoạn tóm tắt, nội dung và một hình ảnh đại diện.

def crawNewsData(baseUrl, url):

    response = requests.get(url)

    soup = BeautifulSoup(response.content, "html.parser")

    titles = soup.findAll('h3', class_='title-news')

    links = [link.find('a').attrs["href"] for link in titles]

    data = []

    for link in links:

        news = requests.get(baseUrl + link)

        soup = BeautifulSoup(news.content, "html.parser")

        title = soup.find("h2", class_="article-title").text

        abstract = soup.find("h2", class_="sapo").text

        body = soup.find("div", id="main-detail-body")

        content = ""

        try:

            content = body.findChildren("p", recursive=False)[0].text + body.findChildren("p", recursive=False)[1].text

        except:

            content = ""

        image = body.find("img").attrs["src"]

        data.append({

            "title": title,

            "abstract": abstract,

            "content": content,

            "image": image,

        })

    return data