Google có hàng trăm crawler đi thu thập dữ liệu khắp các website trên Internet với trí thông minh và khả năng xử lý mạnh mẽ. Hôm nay chúng ta cùng nhau viết 1 con crawler như vậy, tuy không mạnh mẽ và thông minh như các crawler của Google nhưng nó cũng làm được những tác vụ căn bản nhất: lấy dữ liệu.
Mục đích con robot mà chúng ta sắp viết là nó sẽ truy cập vào một website được chỉ định (hoặc 1 page được chỉ định) và tiến hành index lại tất cả các liên kết, hình ảnh mà nó bắt gặp trên website. Sau khi thực hiện xong 1 page, bạn có thể dụng các liên kết mà crawler này tìm được để di chuyển tiếp tục sang các page khác và tiếp tục index dữ liệu thêm nữa cho đến lúc hết website.
Tuy nhiên, trong bài viết nay chúng ta chỉ tập trung vào việc làm thế nào để tạo ra con crawler làm việc đó. Phần còn lại (xử lý dữ liệu, viết các function nâng cao cho crawler này thì để giành cho các bạn cùng nghiên cứu và chia sẻ nhá :)
Đầu tiên chúng ta cần tạo ra 1 crawler, tôi tạo 1 class Crawler như sau:
class Crawler { } |
Tiếp theo, tiến hành thêm các hàm cần thiết để nó có thể hoạt động. Chúng ta này cần làm 2 việc quan trọng:
- Lấy dữ liệu thô: Tải trang web được chỉ định về.
- Lọc dữ liệu: yêu cầu phía trên của chúng ta là lấy các hình ảnh và liên kết nên chúng ta sẽ lọc chúng.
Theo như yêu cầu trên chúng ta có các hàm sau: hàm getContent() và get(). Hàm getContent($url) có nhiệm vụ lấy dữ liệu từ URL được truyền vào còn hàm get($type) sẽ tùy theo $type mà quyết định sẽ lấy hình ảnh hay liên kết.
class Crawler { protected $content= ''; public function __construct($uri) { } public function getContent() { } public function get($type) { } protected function _get_images() { } protected function _get_links() { } } |
Phụ mục
Lấy dữ liệu thô
Code hàm getContent và _construct được code như sau
public function __construct($uri) { $this->content = $this->getContent($uri); } public function getContent($uri) { return file_get_contents($uri); } |
Lọc dữ liệu
Các hàm còn lại của đối tượng Crawler ở trên
public function get($type) { $method = "_get_{$type}"; if (method_exists($this, $method)){ return call_user_method($method, $this); } } protected function _get_images() { if (!empty($this->content)){ preg_match_all('/<img([^>]+)\/>/i', $this->content, $images); return !empty($images[1]) ? $images[1] : FALSE; } } protected function _get_links() { if (!empty($this->content)){ preg_match_all('/<a([^>]+)\>(.*?)\<\/a\>/i', $this->content, $links); return !empty($links[1]) ? $links[1] : FALSE; } } |
Code hoàn chỉnh
Đây là em nó sau cùng
class Crawler { protected $content= ''; public function __construct($uri) { $this->content= $this->getContent($uri); } public function getContent($uri) { return file_get_contents($uri); } public function get($type) { $method = "_get_{$type}"; if (method_exists($this, $method)){ return call_user_method($method, $this); } } protected function _get_images() { if (!empty($this->content)){ preg_match_all('/]+)\/>/i', $this->content, $images); return !empty($images[1]) ? $images[1] : FALSE; } } protected function _get_links() { if (!empty($this->content)){ preg_match_all('/]+)\>(.*?)\<\/a\>/i', $this->content, $links); return !empty($links[1]) ? $links[1] : FALSE; } } } |
Sử dụng con Crawler này như thế nào
Cần lưu ý là con crawler như ở trên chỉ có thể duyệt được 1 trang duy nhất theo URL được truyền vào. Để duyệt được nhiều trang bạn chỉ việc duyệt 1 trang đầu tiên và lặp lại mảng kết quả (URL) để tiếp tục duyệt các URL được tìm thấy.
$crawl = new Crawler('http://nhanweb.com'); $images = $crawl->get('images'); $links = $crawl->get('links'); |
Biến $images và $links nhận được là dạng mảng. Phần mở rộng cho con crawler này để thực hiện các chức năng khác mời các bạn bổ sung cũng như hoàn thiện thêm :)
tut4ever says
Chẳng hiều cái môt tê gì cả :D :(( :(( :((
.-= Bài viết mới tại tut4ever´s blog ..Hello world! =-.
Anh Vũ says
Giúp mình với, mình đang viết 1 demo web crawler bằng asp, nhưng khó quá, bạn có thể share cho mình 1 cái demo đơn giản để mình tham khảo được không, mình cảm ơn bạn rất nhiều !!!
Y5cafe says
Tặng bác
http://vision-media.ca/resources/php/create-a-php-web-crawler-or-scraper-5-minutes
ronytran says
Tôi xem xong chẳng hiểu sử dụng như thế nào, bạn hướng dẫn cách sử dụng thêm dược nữa không?
Thanks :)
Đầm công sở says
Cũng chưa hiểu lắm. Anh Nhân có thể ghi thêm chú thích vào từng đoạn code đươc không anh
Hùng Nguyễn says
Mình nghĩ bạn nên sửa lại 1 chút để có thể sử dụng cả CUrl và file_get_contents, vì có nhiều hosting không cho sử dụng hàm file_get_contents.
Bài viết rất hay và hữu ích cho người mới bắt đầu tìm hiểu về bot và thu thập dữ liệu = bot.
:D
Tên vi phạm says
A ơi, khi viết code a có thể đính kèm file zip hoặc thêm ô copy cho mobile có thể xem + code dc không ạ ?
Bọn e online mobile thì không thể xem + copy code dc.
Tên vi phạm says
Cách thức hoạt động này có giống google không nhỉ để theo dõi diễn đàn mới của em
Nim says
Có cách nào vượt qua các web dùng Ajax hoặc token hoặc các biện pháp chống crawl như shopee hoặc lazada không ah?