images
27/10/2020 05:29 am

Python ứng dụng: Crawl trang web bằng Scrapy

Như mọi người đã biết, python được ứng dụng rất nhiều trong cuộc sống. Và hôm nay Techzone sẽ nói về một trong số đó: ứng dụng của python trong việc crawl dữ liệu.

Khi làm data mining điều đầu tiên mà chúng ta cần là data, thế nhưng không phải lúc nào data cũng có sẵn, việc tracking để lấy data mới cũng phụ thuộc vào số người vào ứng dụng của chúng ta. Lúc đấy chúng ta có thể nghĩ tới việc lấy dữ liệu từ một nguồn khác: các trang web trên internet. Và việc lấy dữ liệu tự động từ các trang web đấy được gọi là crawl.


Xét trên góc nhìn crawl, nội dung trên một trang web thì có hai kiểu:

- Nội dung được load tĩnh: Đây là nội dung trả về ngay khi người dùng truy cập vào web. (Bạn có thể dùng lệnh curl, ví dụ: curl https://kenh14.vn để xem)

- Nội dung được load động: Đây là nội dung trả về từ các request ajax


Với nội dung load động, chúng là có thể dùng selenium hay phantomjs để crawl. Tuy nhiên trong bài này Techzone sẽ chỉ tập trung vào một thư viện phù hợp hơn với việc crawl nội dung tĩnh: scrapy


Có bạn có hỏi bọn mình là giờ nhiều trang web được build bằng ajax rồi, thì việc crawl nội dung tĩnh có còn có ý nghĩa hay không?


Thực ra thì để tăng điểm SEO nên có rất nhiều nội dung bắt buộc để tĩnh, thậm chí trước phát triển theo kiểu động, sau lại phải convert về kiểu tĩnh. Bởi vậy nên cho tới hiện tại crawl nội dung tĩnh vẫn là cách làm rất hiệu quả.


Và phần tiếp theo, mình sẽ tập trung nói về scrapy nhé.


Scrapy là một thư viện rất phổ biến và hiệu quả trong việc crawl dữ liệu. Lợi thế của scrapy không chỉ ở việc support sẵn các hàm thư viện, mà nó còn đặc biệt ở chỗ nó định nghĩa luôn cả quy trình cũng như kiến trúc để lấy dữ liệu về. Và theo mình kiến trúc, quy trình đấy rất clear và dễ nắm bắt, giúp chúng ta nhẹ đầu hơn, đỡ phải ngồi nghĩ kiến trúc.


  • Trước hết về kiến trúc Scrappy

Hình phía dưới mô tả kiến trúc của scrapy

Bạn nhìn trong hình sẽ thấy các thành phần:


Scheduler: nó sẽ định nghĩa các url được crawl cũng như thứ tự, và thời gian crawl các trang đó.


Downloader: thực hiện việc lấy dữ liệu về. Quản lý các lỗi khi download. Chống trùng lặp.


Spiders: bóc tách dữ liệu lấy về từ trang web, thành các nội dung mà chúng ta muốn lấy.


Item Pipeline: xử lý dữ liệu bóc tách được và lưu và db.


Scrapy Engine: quản lý các thành phần trên.


Khi dùng lệnh scrapy tạo project thì nó sẽ tạo ra các file tương ứng với các thành phần này. Chút nữa trong phần thực hành mình sẽ chỉ lại cho các bạn nhé.


  • Tiếp theo, về luồng dữ liệu 


Tip: Nếu phần này bạn đọc xong thấy khó hình dung, có thể xem tiếp ở phần thực hành, sẽ dễ hiểu hơn


1. Khi bắt đầu crawl một website, Engine sẽ xác định tên miền và tìm vị trí của spider đó và yêu cầu spider đó tìm các urls đầu tiên để crawl


2. Engine nhận danh sách các urls đầu tiên từ spider, gửi cho Scheduler để sắp xếp


3. Engine yêu cầu danh sách cách urls tiếp theo từ Scheduler


4. Engine nhận danh sách các url tiếp theo từ Scheduler vào gửi đến Downloader (requests)


5. Downloader nhận request và thực hiện việc tải trang, sau khi tải xong sẽ tạo một response và gửi lại Engine


6. Response từ Downloader sẽ được Engine đẩy qua Spiders để xử lý


7. Tại Spiders, khi nhận được response, chúng bóc tách thông tin từ response (title, content, author, date publish...) và những url có khả năng để crawl và đẩy lại cho Engine (requests)


Ở bước này, Engine nhận được kết quả từ Spiders sẽ thực hiện 2 công việc: đẩy những dữ liệu đã được bóc tách tới Item Pipeline để xử lý và lưu vào Databases, đẩy những url mới (requests) mới về Scheduler và quay về bước 3.


8. Kiểm tra nếu không còn request thì quá trình crawl sẽ kết thúc


Phần trên là lý thuyết kiến trúc scrapy, còn chúng ta sẽ phải làm gì để dùng scrapy để crawl một trang web?


- Trước hết chúng cài đặt scrapy


À mà bạn nhớ phải có python 3.6+ trước nhé. Nếu bạn chưa biết cài python thì có thể tham khảo TẠI ĐÂY


- Khi đã có scrapy, chúng ta sẽ thực hành thông qua những bước sau:


1. Tạo mới Scrapy project


2. Viết 1 spider để crawl một trang web: chẳng hạn kênh14


3. Xuất dữ liệu crawl bằng commandline


4. Thay đổi spider để crawl recursively (Nghĩa là thấy link trả về trong nội dung web thì tiến hành crawl tiếp)


5. Sử dụng các tùy biến của spider 

1. Tạo mới Scrapy project

Bạn tạo một thư mục để lưu project, vào thư mục đó và chạy lệnh:


scrapy startproject tutorial


Scrapy sẽ tự động tạo ra các thư mục và file như sau:


tutorial/

    scrapy.cfg           # file chứa cấu hình khi deploy


    tutorial/            # project's Python module, chúng ta sẽ code trong thư mục này

        __init__.py


        items.py         # project items definition file


        middlewares.py    # project middlewares file


        pipelines.py      # project pipelines file


        settings.py       # project settings file


        spiders/          # thư mục chúng ta đặt các file spiders

            __init__.py


2. Viết 1 spider để crawl http://kenh14.vn/fashion/lam-dep.chn 


import scrapy

import datetime



class Kenh14Spider(scrapy.Spider):

   name = "kenh14"



   def start_requests(self):

       urls = [

           'http://kenh14.vn/fashion/lam-dep.chn',

       ]

       for url in urls:

           yield scrapy.Request(url=url, callback=self.parse)



   def parse(self, response):

       result = {

           'title': response.css('.kbw-content,  h1.kbwc-title::text').extract_first().strip(),

           'author': response.css('.kbw-content .kbwc-meta .kbwcm-author::text').extract_first().strip(),

           'source': 'kenh14',

           'content': response.css('.klw-new-content').extract_first().strip(),

           'link': response.request.url,

           'modifiedDate': datetime.now()

       }

       print(str(result))

       yield result


Trong spider chúng ta cần chú ý các thành phần sau:


name: Là tên của spider, sau này sẽ được sử dụng để gọi crawl (Xem bước 3).


Bạn có thể có nhiều spider tương ứng nhiều trang web khác nhau trong project của bạn. Vì vậy bạn nên đặt tên nó sát tên trang web chút cho dễ quản lý.


start_urls: Danh sách các url bắt đầu để crawl


parse: Hàm bóc tách nội dung. Ở hàm này chúng ta làm hai việc:


- bóc tách nội dung bằng việc cùng css selector và gán cho object chúng ta cần lưu.


- tìm các link để tiếp tục crawl (đoạn yield response.follow(next_page, self.parse))


Ngoài ra bạn có thể xem thêm ở: https://docs.scrapy.org/en/latest/topics/spiders.html#scrapy.spiders.Spider.name


3. Xuất dữ liệu crawl bằng commandline


Để bắt đầu quá trình crawl bạn ra thư mục ngoài cùng, dùng lệnh:


scrapy crawl kenh14


4. Bổ sung spider để follow tiếp các link:


for next_page in response.css('.kbw-content a::attr(href)').extract():

    yield response.follow(next_page, self.parse)


5. Bạn có thể truyền thông số vào khi chạy command scrapy bằng cách thêm -a:


          scrapy crawl kenh14 -a tag=rapviet 


Thông số này sẽ được truyền vào trong hàm __init__ và trở thành thuộc tính mặc định của spider. Như ví dụ trên khi ta truy cập self.tag sẽ có giá trị là rapviet


Yeah, vậy là bạn đã có thể bắt đầu crawl data từ một trang web. Để tìm hiểu sâu hơn, scrapy được document tại: https://docs.scrapy.org/en/latest/intro/tutorial.htm


Ngoài việc crawl dữ liệu từ internet, thì một phần rất quan trọng nữa là tracking các event của khách hàng hiện tại. Mời các bạn đọc thêm bài Tracking customer behavior nhé.

 

- Tech Zone -


Thư giãn chút nào!!!

Bài viết liên quan