Tìm hiểu cách sử dụng file robots.txt để bảo vệ nội dung website WordPress của bạn khỏi các bot AI thu thập dữ liệu cho các mô hình ngôn ngữ lớn và tìm kiếm AI. Hướng dẫn dễ hiểu và danh sách các bot cần chặn.
Chào các bạn, hôm nay chúng ta sẽ cùng nhau khám phá một cuộc phiêu lưu đầy "drama" trong thế giới lập trình nhé! Chuyện là, sau khi Twitter "kéo thảm" API v2 một cách không thương tiếc, việc truy cập dữ liệu từ nền tảng này trở thành một cơn ác mộng. Mình đã dành hơn 60 tiếng đồng hồ để "stress-test" 4 phương pháp khác nhau, tìm kiếm đâu là giải pháp hiệu quả nhất giữa năm 2025 này. Và tin vui là mình đã tìm ra 'người thắng cuộc'! Đó chính là twitterapi.io, với ưu đãi cực kỳ hấp dẫn: 100.000 credits miễn phí khi đăng ký! Trong khi đó, tự tay cào dữ liệu (DIY scraping) lại tốn kém kinh khủng, có khi lên đến hơn 10 USD/GB chỉ riêng tiền proxy thôi đấy. À, nhân tiện, mình cũng sẽ chia sẻ đoạn code xịn sò cho ai đang dùng Next.js kết hợp với Drizzle ORM luôn. Bật mí thêm, mình đã tạo ra một ứng dụng tên là The Roast Bot (các bạn có thể xem tại https://theroastbot.com) – và nó đã khiến CEO của Y Combinator phải chặn mình chỉ trong 48 giờ! Nghe hấp dẫn không? Cùng bắt đầu thôi! <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/TwitterAPICollapse.png' alt='Twitter API bị kéo thảm'> Cách đây vài tuần, bài "ca thán" của mình về việc Twitter API "sập tiệm" đã gây bão trên Reddit với hơn 245.000 lượt xem. Mình nhận được vô số gợi ý về các giải pháp thay thế, và mình xin gửi lời cảm ơn chân thành tới tất cả các bạn đã giúp đỡ! Mình đã lao vào thử nghiệm từng phương án một, trong điều kiện thực tế nhất. Kết quả là gì ư? Hãy xem tiếp nhé! Giờ thì, hãy cùng điểm mặt 4 "chiến binh" mà mình đã thử nghiệm trong hành trình đầy chông gai này nhé! Coi như 4 con đường đi qua "vùng đất hoang" vậy. <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/Contenders.png' alt='4 phương pháp truy cập dữ liệu Twitter'> **1. Tự host Nitter: Cái bẫy của những người mộng mơ** (https://github.com/zedeus/nitter) Nitter nghe có vẻ "trong mơ": một giao diện Twitter mã nguồn mở, tập trung vào quyền riêng tư, thậm chí có cả RSS feeds. Nghe là thấy mê rồi đúng không? <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/NitterLogo.png' alt='Nitter Logo'> Nhưng thực tế thì... "đời không như là mơ" các bạn ạ! Để cài đặt, bạn chỉ cần vài lệnh cơ bản: `$ git clone https://github.com/zedeus/nitter` `$ docker-compose up -d` Ấy thế mà, bất ngờ chưa? Bạn sẽ phải vật lộn với việc quản lý một "hồ bơi" tài khoản khách và cả proxy nữa! * Ưu điểm: Có toàn quyền kiểm soát quy trình dữ liệu của mình, không lo bị giới hạn bởi bên thứ ba. * Nhược điểm: Phải liên tục thay đổi tài khoản khách (guest account), cứ như chơi trò "mèo vờn chuột" với Twitter vậy. Các instance công cộng (public instances) của Nitter thường "bay màu" chỉ trong vài giờ. Trong quá trình thử nghiệm tải của mình, tỉ lệ thất bại lên đến xấp xỉ 40% – con số này khiến mình "khóc thét". **Đánh giá:** Nitter tuyệt vời cho các dự án cá nhân, "cái tôi" lập trình viên thì khỏi nói, nhưng để dùng cho các ứng dụng chạy thực tế (production) thì... thôi bỏ đi! Nó như một món đồ chơi đẹp, nhưng không đủ bền để "chiến" đâu. **2. API Quản lý (Managed APIs): Lựa chọn của những người thực tế** Nếu bạn là người không thích "đâm đầu vào tường" với Nitter, thì các dịch vụ Managed APIs chính là chân ái! Họ làm hết những việc đau đầu kia cho bạn. **🥇 twitterapi.io - Người chiến thắng của mình!** (https://twitterapi.io) <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/TwitterAPIIOLogo.png' alt='TwitterAPI.io Logo'> * Giá cả "không thể tin nổi": Ngay khi đăng ký, bạn nhận được **100.000 credits miễn phí** (tương đương khoảng 6.600 tweets)! Sau đó, mỗi 1.000 tweets chỉ tốn khoảng 0.15 USD. Đặc biệt, credits đã mua sẽ KHÔNG BAO GIỜ HẾT HẠN. Quá hời đúng không? * Hiệu năng: Khi mình "tra tấn" nó với 1.000 yêu cầu đồng thời, nó vẫn xử lý được **142.51 yêu cầu mỗi giây** – một con số cực kỳ ấn tượng! * Tại sao nó thắng: Có thông số kỹ thuật OpenAPI (OpenAPI spec), giúp việc tích hợp vào các dự án TypeScript của bạn nhanh như chớp. Chấp nhận thanh toán bằng tiền điện tử (crypto) – tiện lợi cho ai thích "ẩn danh". Hỗ trợ Webhook để theo dõi thời gian thực – cực kỳ hữu ích cho các ứng dụng cần sự cập nhật liên tục. * Lưu ý nhỏ: Sau phần credits miễn phí ban đầu, sẽ không có gói miễn phí định kỳ nữa đâu nhé. **🥈 Apify - "Chiếc búa" của các nhà khoa học dữ liệu** (https://apify.com/apify/twitter-scraper) <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/ApifyLogo.png' alt='Apify Logo'> * Giá: Bạn có 5 USD credits miễn phí mỗi tháng, sau đó là khoảng 0.45 USD cho mỗi 1.000 tweets. * Tính năng "sát thủ": Cho phép bạn "cào" followers, lượt thích, hoặc tìm kiếm chỉ bằng vài cú click chuột – cực kỳ thân thiện với người dùng không chuyên code. Có thể xuất dữ liệu thẳng ra S3 hoặc BigQuery – quá tiện lợi cho các dự án dữ liệu lớn. Xử lý hàng triệu công việc "tweet" dễ như trở bàn tay. * Cảnh báo: Chi phí có thể "đội lên" chóng mặt nếu bạn không tối ưu hóa scraper của mình đấy nhé! **3. Tự tay "cào" dữ liệu (DIY Scraping): Cái hố sâu của sự đau khổ** À, đây rồi, con đường dành cho những ai thích "tự hành hạ mình" hoặc muốn có toàn quyền kiểm soát tối đa! Mình đã thử dùng các công cụ như: * the-convocation/twitter-scraper (https://github.com/the-convocation/twitter-scraper) * Playwright (https://playwright.dev) * Và đặc biệt là các loại proxy "dân cư" (residential proxies) từ IPRoyal (https://iproyal.com), với giá "cắt cổ" 15 USD/GB! <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/DIYScraping.png' alt='Tự cào dữ liệu'> **Sự thật phũ phàng:** Bạn sẽ... "ghét cuộc đời" mình luôn đấy! * Ưu điểm: Sự linh hoạt tuyệt đối – bạn muốn làm gì thì làm, không ai cấm! * Nhược điểm: Tốn hơn **15 tiếng mỗi tuần** chỉ để duy trì các scraper – cứ như nuôi con mọn vậy. Chi phí proxy "đốt tiền" khủng khiếp: từ 10 đến 50 USD mỗi ngày! Và tệ nhất: tài khoản Twitter cá nhân của bạn sẽ bị "ban" (khóa) không thương tiếc! **☠️ Những bài học xương máu (trả giá bằng "máu")** Trong quá trình "chinh chiến" này, mình đã rút ra được vài bài học cực kỳ quý giá, mà có khi phải trả giá bằng "máu và nước mắt" mới có được đấy! * Ứng dụng của mình (@TheRoastBotApp) bị hạn chế vì "hành vi không xác thực" chỉ sau 48 giờ. Twitter không phải dạng vừa đâu, các bạn đừng đùa! * Proxy "dân cư" không phải là "áo choàng tàng hình" đâu nhé! Twitter cực kỳ tinh vi trong việc "nhận diện" trình duyệt và stack mạng của bạn. Dù bạn có dùng proxy cao cấp đến mấy, họ vẫn có thể "đọc vị" được. <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/TwitterFingerprint.png' alt='Twitter nhận diện dấu vân tay trình duyệt'> * Hãy luôn trừu tượng hóa lớp dữ liệu của bạn! Đây là một "mẹo" đã cứu sống mình. Tưởng tượng thế này: thay vì trực tiếp gọi Twitter API trong mọi ngóc ngách code của bạn, hãy tạo ra một "giao diện chung" (interface) cho việc lấy dữ liệu mạng xã hội. Ví dụ như thế này này: ```typescript interface SocialDataSource { getUserTweets(userId: string): Promise<Tweet[]>; } ``` Rồi bạn sẽ có các lớp (class) khác nhau để triển khai giao diện đó, ví dụ: ```typescript class TwitterAPI implements SocialDataSource { /* ... */ } class ApifySource implements SocialDataSource { /* ... */ } ``` Ưu điểm: Khi Twitter "giở trò" hay bạn muốn chuyển sang một nguồn dữ liệu khác, bạn chỉ cần thay đổi "bộ não" bên dưới thôi, còn phần còn lại của ứng dụng không cần biết gì cả. Giống như bạn rút phích cắm một thiết bị và cắm thiết bị khác vào mà ổ điện vẫn y nguyên vậy! Dễ dàng "hoán đổi" mà không cần sửa quá nhiều code. <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/AbstractionLayer.png' alt='Lớp trừu tượng hóa dữ liệu'> **💻 "Mổ xẻ" kỹ thuật: Next.js + Drizzle ORM** Bạn muốn biết mình đã xây dựng ứng dụng The Roast Bot như thế nào ư? Đây là kiến trúc tổng thể mà mình đã áp dụng, sử dụng Next.js và Drizzle ORM – một bộ đôi cực kỳ mạnh mẽ cho các ứng dụng hiện đại! <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/NextjsDrizzleArchitecture.png' alt='Kiến trúc Next.js và Drizzle ORM'> * Next.js App Router: Đây là "bộ não" chính của ứng dụng web, chịu trách nhiệm xử lý các yêu cầu từ người dùng. * twitterapi.io: Khi cần lấy dữ liệu tweets, Next.js sẽ gọi đến API của twitterapi.io – người bạn thân đã cứu sống dự án của mình. * PostgreSQL: Dữ liệu tweets sau khi lấy về sẽ được lưu trữ an toàn trong cơ sở dữ liệu PostgreSQL. * Drizzle ORM: Đây là "người phiên dịch" giúp ứng dụng Next.js của mình dễ dàng giao tiếp với PostgreSQL. Thay vì viết những câu lệnh SQL dài dòng, mình dùng Drizzle để thao tác với dữ liệu một cách trực quan hơn rất nhiều. * The Roast Bot Frontend: Và tất nhiên, toàn bộ dữ liệu sẽ được hiển thị trên giao diện người dùng "siêu mượt" của The Roast Bot. **Cách triển khai (ngắn gọn thôi nhé):** 1. Kết nối đến cơ sở dữ liệu (trong lib/twitter.ts - tên file này có vẻ hơi sai tí so với nội dung, nhưng ý là lib/db.ts): Chúng ta dùng postgres để tạo kết nối và drizzle để "biến hóa" kết nối đó thành một đối tượng ORM dễ dùng. ```typescript import { drizzle } from 'drizzle-orm/postgres-js'; import postgres from 'postgres'; const connection = postgres(process.env.DATABASE_URL!); export const db = drizzle(connection); export const getTweets = async (userId: string) => { const res = await fetch( `https://api.twitterapi.io/v1/user_tweets?user_id=${userId}`, { headers: {'x-api-key': `${process.env.TWITTERAPI_KEY}` } } ); return res.json(); }; ``` 2. Định nghĩa cấu trúc bảng (trong drizzle/schema.ts): Đây là nơi chúng ta mô tả bảng tweets trong database sẽ trông như thế nào. Có ID, ID người dùng, nội dung tweet và thời gian "cào" dữ liệu. ```typescript import { pgTable, text, timestamp } from 'drizzle-orm/pg-core'; export const tweets = pgTable('tweets', { id: text('id').primaryKey(), userId: text('user_id').notNull(), content: text('content').notNull(), scrapedAt: timestamp('scraped_at').defaultNow(), }); ``` 3. API endpoint để nhập dữ liệu (trong app/api/ingest/route.ts): Khi frontend gửi yêu cầu đến /api/ingest, chúng ta sẽ lấy userId, dùng getTweets để lấy dữ liệu tweets từ twitterapi.io, rồi "nhét" thẳng vào database thông qua Drizzle. Nếu tweet đã tồn tại (dựa trên ID), nó sẽ bỏ qua để tránh trùng lặp. ```typescript import { db } from '@/lib/db'; import { tweets } from '@/drizzle/schema'; export async function POST(req: Request) { const { userId } = await req.json(); const tweetData = await getTweets(userId); await db.insert(tweets).values(tweetData).onConflictDoNothing(); return new Response(JSON.stringify({ success: true }), { status: 200, headers: { 'Content-Type': 'application/json' } }); } ``` Nghe có vẻ "pro" nhưng thực ra khá là logic và dễ hiểu đúng không nào? **🏆 Lời phán quyết cuối cùng!** Sau tất cả, đây là bảng tổng kết cho các bạn dễ hình dung về 4 "chiến binh" của chúng ta:
Chào mừng bạn trở lại với series "Cuộc Đua Code Chống Lại Thời Gian!" – nơi chúng ta biến những công việc nhàm chán thành những siêu phẩm tự động, tiết kiệm từng giây vàng ngọc. Hôm nay, tôi cực kỳ hào hứng chia sẻ một dự án mà tôi đã biến một công việc thủ công lặp đi lặp lại thành một cỗ máy tự động siêu phàm! Sẵn sàng để xem làm thế nào bạn có thể tiết kiệm thời gian và thêm chút "gia vị" thú vị vào quy trình làm việc của mình chưa? Bắt đầu thôi nào! Chuyện hậu trường: Làm việc ở một startup đúng là có nhiều điều thú vị, ví dụ như cơ hội được hợp tác với đủ phòng ban và "khai quật" những điểm chưa hiệu quả, chín muồi để tự động hóa. Trong một buổi trò chuyện gần đây với đội Marketing, tôi đã phát hiện ra một công việc mà phải nói là... "cầu xin" được nâng cấp bằng công nghệ! Họ đang hàng ngày làm những việc này một cách thủ công: Truy cập Product Hunt mỗi ngày để lấy 5 sản phẩm hot nhất. Thu thập thông tin mạng xã hội của từng "nhà sáng tạo" ra sản phẩm đó. Lặp đi lặp lại quy trình này... mỗi ngày! <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6d5e6psjv9rqykvqu95.png' alt='Giao diện Product Hunt'> Ngay khi nghe xong, tôi nghĩ ngay: "Tại sao mình không tự động hóa nó nhỉ?" Thế là tôi túm ngay lấy laptop và bắt đầu "gõ code" thôi! Phân tích vấn đề (hay là "Mổ xẻ" cái khó): Để "xử lý" công việc này, tôi cần xây dựng một "công cụ cào dữ liệu" (hay còn gọi là scraper). Nghe thì có vẻ "hack não" nhưng thực ra không hề phức tạp đâu, cứ như bạn đang "thu gom" thông tin vậy đó! Đây là cách tôi đã tiếp cận nó: 1. "Thăm dò" cấu trúc Product Hunt: Đầu tiên, tôi phải tìm hiểu xem Product Hunt hiển thị nội dung như thế nào và họ sử dụng API gì. Hóa ra, trang này dùng phương pháp "server-side rendering" (SSR) – nghĩa là máy chủ đã chuẩn bị sẵn sàng dữ liệu và giao diện rồi, trình duyệt của chúng ta chỉ việc "hiển thị" thôi. Việc này quan trọng vì nó ảnh hưởng đến công cụ mình chọn. 2. Chọn "đồ nghề": Vì trang web dùng SSR, tôi quyết định dùng Puppeteer kết hợp với Node.js. Puppeteer giống như một "chàng đạo diễn" tài ba, cho phép chúng ta điều khiển một trình duyệt web "không đầu" (headless browser) – tức là trình duyệt chạy ngầm, không có giao diện đồ họa. Nó sẽ giúp chúng ta "cào" dữ liệu y hệt như khi bạn đang lướt web thủ công vậy đó, nhưng nhanh hơn gấp vạn lần! 3. "Hốt" dữ liệu về: 5 sản phẩm hot nhất: Tôi bắt đầu bằng việc dùng Puppeteer để "lướt" trang Product Hunt và lấy về danh sách 5 sản phẩm đứng top trong ngày. Thông tin chi tiết sản phẩm: Với mỗi sản phẩm, tôi lại "nhấp chuột" vào để lấy ID của nó. Cái ID này quan trọng lắm nha. Thông tin "nhà sáng tạo": Dùng cái ID sản phẩm vừa lấy được, tôi lại "đột nhập" vào một API của Product Hunt để "moi" thông tin chi tiết về người đã tạo ra sản phẩm đó. Thông tin mạng xã hội: Có được ID của "nhà sáng tạo" rồi, tôi lại tiếp tục dùng Puppeteer để "ghé thăm" trang cá nhân của từng người và "quét sạch" thông tin mạng xã hội của họ. 4. Lưu trữ dữ liệu: Cuối cùng, tất cả những thông tin "quý báu" này được tổng hợp gọn gàng vào một file CSV (giống như một bảng tính Excel đơn giản vậy), giúp đội Marketing dễ dàng "tiêu hóa" và sử dụng. Đây là ví dụ về file CSV sau khi được "gom" dữ liệu: <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ouevnpx2rdnrdf422xnr.png' alt='Dữ liệu sản phẩm và người tạo trong file CSV'> Tại sao việc này lại "đáng giá" thế? Việc tự động hóa những công việc này không chỉ giúp tiết kiệm hàng tấn thời gian mà còn giảm thiểu tối đa sai sót do con người gây ra. Đảm bảo đội Marketing luôn có dữ liệu mới nhất trong tầm tay, không cần phải lo lắng gì nữa! Hơn nữa, đây là một ví dụ tuyệt vời cho thấy công nghệ có thể biến những nhiệm vụ lặp đi lặp lại thành những thứ cực kỳ hiệu quả và mang lại giá trị cao. Ghi chú nhỏ: Nếu bạn muốn có "bí kíp" (source code) này, cứ thoải mái "ping" tôi nhé! Đến lượt bạn rồi! Bạn đã bao giờ tự động hóa một công việc nào đó bằng code chưa? Hãy chia sẻ những trải nghiệm và "mẹo" của bạn ở phần bình luận bên dưới nhé! Công việc nào mà bạn ước gì có thể tự động hóa được? Cùng thảo luận thôi nào! Cuối cùng, nếu bài viết này hữu ích, đừng ngần ngại vỗ tay 👏 và follow tôi nhé! Cảm ơn bạn rất nhiều!