Hướng dẫn cạo các trang web động với Python

Bình luận: 0

Một khả năng quan trọng để có được dữ liệu từ các trang web là quét web. Pinterest và Instagram, tải nội dung tự động thông qua tương tác người dùng với chúng là những ví dụ về các loại trang web này. Các phương pháp cạo thông thường là không đủ khi xử lý vật liệu dựa trên JavaScript. Trong bài viết này, chúng tôi sẽ trình bày về nhà viết kịch là công cụ tự động hóa trong khi LXML sẽ được sử dụng để trích xuất dữ liệu từ các trang web động như vậy yêu cầu JavaScript hoạt động đúng. Trên lưu ý này, chúng tôi có thể thảo luận về việc sử dụng các proxy trong nhà viết kịch để trốn tránh phát hiện dưới dạng bot. Trong hướng dẫn này, chúng tôi sẽ xóa hồ sơ Instagram để truy xuất tất cả các URL bài viết bằng cách mô phỏng hành vi của người dùng, chẳng hạn như cuộn và chờ đợi các bài đăng tải.

Các công cụ chúng tôi sẽ sử dụng trong hướng dẫn này:

  • Nhà viết kịch (cho tự động hóa trình duyệt);
  • LXML (để trích xuất dữ liệu bằng XPath);
  • Python (như ngôn ngữ lập trình của chúng tôi).

Hướng dẫn từng bước để xóa các bài đăng trên Instagram

Chúng tôi sẽ minh họa quá trình bằng cách sử dụng ví dụ về việc xóa cấu hình Instagram để trích xuất URL POST, mô phỏng các hành động của người dùng như cuộn qua trang và chờ dữ liệu mới tải. Các trang web động không đồng bộ tải nội dung của họ thông qua các yêu cầu AJAX, có nghĩa là không phải tất cả nội dung trang đều có thể truy cập ngay lập tức.

Bước 1. Cài đặt thư viện bắt buộc

Trước khi chúng tôi bắt đầu, hãy cài đặt các gói cần thiết:


pip install playwright
pip install lxml

Bạn cũng sẽ cần cài đặt trình duyệt nhà viết kịch:


playwright install

Bước 2. Thiết lập nhà viết kịch cho trang web động cạo

Chúng tôi sẽ sử dụng nhà viết kịch để tự động hóa trình duyệt, tải nội dung động của Instagram và cuộn qua trang để tải nhiều bài đăng hơn. Hãy tạo tập lệnh tự động hóa cơ bản:

Tập lệnh tự động hóa (Trình duyệt không đầu):


import asyncio
from playwright.async_api import async_playwright

async def scrape_instagram():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)  # Chế độ không đầu không có phản hồi trực quan
        page = await browser.new_page()
        
        # Truy cập URL hồ sơ
        await page.goto("https://www.instagram.com/profile name/", wait_until="networkidle")

        # Nhấp vào nút để tải thêm bài viết
        await page.get_by_role("button", name="Show more posts from").click()
        
        # Cuộn trang để tải nội dung động
        scroll_count = 5  # Tùy chỉnh điều này dựa trên số lần bạn muốn cuộn
        for _ in range(scroll_count):
            await page.evaluate('window.scrollBy(0, 700);')
            await page.wait_for_timeout(3000)  # Chờ các bài viết để tải
            await page.wait_for_load_state("networkidle")
        
        # Nhận nội dung trang
        content = await page.content()
        await browser.close()
        
        return content

# Chạy chức năng không đồng bộ
asyncio.run(scrape_instagram())

Bước 3. Phân tích trang với LXML và XPath

Khi nội dung được tải, chúng ta có thể sử dụng LXML để phân tích HTML và trích xuất dữ liệu bằng XPath. Trong trường hợp này, chúng tôi đang trích xuất URL của tất cả các bài đăng từ hồ sơ.

Phân tích nội dung trang và trích xuất URL bài đăng:


from lxml import html
import json

def extract_post_urls(page_content):
    # Phân tích nội dung HTML bằng LXML
    tree = html.fromstring(page_content)
    
    # XPath để trích xuất URL bài đăng
    post_urls_xpath = '//a[contains(@href, "/p/")]/@href'
    
    # Trích xuất URL
    post_urls = tree.xpath(post_urls_xpath)
    
    # Chuyển đổi URL tương đối thành Tuyệt đối
    base_url = "https://www.instagram.com"
    post_urls = [f"{base_url}{url}" for url in post_urls]
    
    return post_urls

Chức năng ví dụ để lưu dữ liệu được trích xuất ở định dạng JSON:


def save_data(profile_url, post_urls):
    data = {profile_url: post_urls}
    with open('instagram_posts.json', 'w') as json_file:
        json.dump(data, json_file, indent=4)

# Cạo và chiết xuất URL
page_content = asyncio.run(scrape_instagram())
post_urls = extract_post_urls(page_content)

# Lưu các URL được trích xuất trong tệp JSON
save_data("https://www.instagram.com/profile name/", post_urls)

Bước 4. Xử lý cuộn vô hạn với nhà viết kịch

Để cạo các trang web động, bạn thường cần mô phỏng cuộn vô hạn. Trong tập lệnh của chúng tôi, chúng tôi cuộn trang bằng JavaScript:


(window.scrollBy(0, 700))

Và đợi nội dung mới tải bằng lệnh này:


 wait_for_load_state("networkidle")

Bước 5. Sử dụng proxy với nhà viết kịch

Instagram có giới hạn tỷ lệ nghiêm ngặt và các biện pháp chống BOT. Để tránh bị chặn, bạn có thể sử dụng proxy để xoay địa chỉ IP và phân phối các yêu cầu. Nhà viết kịch giúp bạn dễ dàng tích hợp các proxy vào tự động hóa cào của bạn.

Thực hiện proxy trong nhà viết kịch:


async def scrape_with_proxy():
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=False, 
            proxy={"server": "http://your-proxy-server:port"}
        )
        page = await browser.new_page()
        await page.goto("https://www.instagram.com/profile name/", wait_until="networkidle")
        # Tiếp tục cạo như trước ...

Nhà viết kịch cũng hỗ trợ proxy được truyền khi mật khẩu tên người dùng và ví dụ máy chủ được đưa ra dưới đây.


async def scrape_with_proxy():
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=False, 
            proxy={"server": "http://your-proxy-server:port", "username": "username", "password": "password"}
        )
        page = await browser.new_page()
        await page.goto("https://www.instagram.com/profile name/", wait_until="networkidle")
        # Tiếp tục cạo như trước ...

Các proxy giúp tránh các lệnh cấm IP, các thách thức CAPTCHA và đảm bảo xóa trơn các trang web nặng về dữ liệu hoặc bị hạn chế như Instagram.

Hoàn thành mã


import asyncio
from playwright.async_api import async_playwright
from lxml import html
import json

# Chức năng tự động hóa trình duyệt và cạo nội dung động với proxy
async def scrape_instagram(profile_url, proxy=None):
    async with async_playwright() as p:
        # Thiết lập trình duyệt với proxy nếu được cung cấp
        browser_options = {
            'headless': True,  # Sử dụng trình duyệt Headed để xem hành động (có thể được đặt thành True cho chế độ không đầu)
        }
        if proxy:
            browser_options['proxy'] = proxy

        # Khởi chạy trình duyệt
        browser = await p.chromium.launch(**browser_options)
        page = await browser.new_page()

        # Truy cập trang hồ sơ Instagram
        await page.goto(profile_url, wait_until="networkidle")
        
        # Hãy thử nhấp vào nút "Hiển thị thêm bài đăng" (tùy chọn, có thể không tìm thấy nút nếu không tìm thấy nút)
        try:
           await page.click('button:has-text("Show more posts from")')
        except Exception as e:
           print(f"No 'Show more posts' button found: {e}")


        # Cuộn trang để tải thêm bài viết
        scroll_count = 5  # Số lượng cuộn để tải bài đăng
        for _ in range(scroll_count):
            await page.evaluate('window.scrollBy(0, 500);')
            await page.wait_for_timeout(3000)  # Chờ các bài đăng mới tải
            await page.wait_for_load_state("networkidle")

        # Nhận nội dung trang đầy đủ sau khi cuộn
        content = await page.content()
        await browser.close()  # Đóng trình duyệt một khi đã hoàn thành
        
        return content

# Chức năng phân tích nội dung trang bị xóa và trích xuất URL bài đăng
def extract_post_urls(page_content):
    # Phân tích nội dung HTML bằng LXML
    tree = html.fromstring(page_content)
    
    # XPath để trích xuất URL bài đăng
    post_urls_xpath = '//a[contains(@href, "/p/")]/@href'
    
    # Trích xuất URL bài sử dụng Xpath
    post_urls = tree.xpath(post_urls_xpath)
    
    # Chuyển đổi URL tương đối thành URL tuyệt đối
    base_url = "https://www.instagram.com"
    post_urls = [f"{base_url}{url}" for url in post_urls]
    
    return post_urls

# Chức năng để lưu URL bài đăng được trích xuất vào tệp JSON
def save_data(profile_url, post_urls):
    # Cấu trúc dữ liệu ở định dạng JSON
    data = {profile_url: post_urls}
    
    # Lưu dữ liệu vào một tệp
    with open('instagram_posts.json', 'w') as json_file:
        json.dump(data, json_file, indent=4)
    print(f"Data saved to instagram_posts.json")

# Chức năng chính để chạy cào và lưu dữ liệu
async def main():
    # Xác định URL cấu hình Instagram
    profile_url = "https://www.instagram.com/profile name/"
    
    # Tùy chọn, thiết lập proxy
    proxy = {"server": "server", "username": "username", "password": "password"}  # Không sử dụng nếu không cần proxy
    
    # Cạo trang Instagram với proxy
    page_content = await scrape_instagram(profile_url, proxy=proxy)
    
    # Trích xuất các URL bài viết từ nội dung trang bị xóa
    post_urls = extract_post_urls(page_content)
    
    # Lưu các URL bài được trích xuất vào tệp JSON
    save_data(profile_url, post_urls)

if __name__ == '__main__':
   asyncio.run(main())

Các công cụ tự động hóa thay thế để cạo web

Mặc dù nhà viết kịch là một lựa chọn tuyệt vời để cạo các trang web động, các công cụ khác có thể phù hợp cho các tình huống khác nhau:

  1. Selenium: Selenium là một trong những khung tự động hóa trình duyệt lâu đời nhất và hoạt động tương tự như nhà viết kịch. Nó rất linh hoạt nhưng thiếu một số khả năng hiện đại mà nhà viết kịch cung cấp, chẳng hạn như xử lý nhiều trình duyệt với một API duy nhất;
  2. Puppeteer: Puppeteer là một công cụ phổ biến khác để tự động hóa trình duyệt, đặc biệt là để loại bỏ các trang web nặng JavaScript. Giống như nhà viết kịch, nó điều khiển các trình duyệt không đầu và cho phép tương tác với nội dung động;
  3. Yêu cầu + BeautifulSoup: Đối với các trang web đơn giản hơn mà không yêu cầu JavaScript tải nội dung, thư viện yêu cầu kết hợp với BeautifulSoup là một sự thay thế nhẹ. Tuy nhiên, nó không xử lý nội dung động tốt.

Mỗi công cụ cung cấp các thế mạnh độc đáo và có thể được chọn dựa trên các nhu cầu và điều kiện cụ thể của dự án.

Để thực hiện thành công các trang web động, chủ động sử dụng các yêu cầu JavaScript và AJAX, các công cụ mạnh mẽ có khả năng xử lý hiệu quả cuộn vô hạn và các yếu tố tương tác phức tạp là cần thiết. Một giải pháp như vậy là nhà viết kịch, một công cụ từ Microsoft cung cấp tự động hóa trình duyệt đầy đủ, làm cho nó trở thành một lựa chọn lý tưởng cho các nền tảng như Instagram. Kết hợp với thư viện LXML để phân tích cú pháp HTML, nhà viết kịch đơn giản hóa rất nhiều trích xuất dữ liệu, cho phép tự động hóa các tương tác với các yếu tố trang và quy trình phân tích cú pháp mà không cần can thiệp thủ công. Ngoài ra, việc sử dụng các máy chủ proxy giúp tránh bảo vệ chống BOT và ngăn chặn việc chặn IP, đảm bảo các hoạt động cạo ổn định và không bị gián đoạn.

Bình luận:

0 Bình luận