Thay vì chỉ chạy code thông qua console như trong các phần trước, thì phần này chúng ta sẽ tạo một project Scrapy.
Chúng ta tạo một project Scrapy bằng cách chạy lệnh scrapy startproject <tên_project>
.
D:> scrapy startproject ex New Scrapy project 'ex', using template directory 'd:...', created in: D:\ex You can start your first spider with: cd ex scrapy genspider example example.com
Ở đây chúng ta tạo một project tên là ex ở ổ đĩa D:>, Scrapy sẽ tạo một thư mục mang tên ex trong ổ đĩa D:>.
D:> cd ex D:/ex> tree D:. |___ex |___spiders | |___ __pycache__ |____ __pycache__
Đoạn code bên trên sẽ cho chúng ta biết những thư mục con và file đã được Scrapy tạo ra bên trong thư muc ex.
Trong đó có 3 file đáng lưu ý là items.py
,pipelines.py
và settings.py
. Ngoài ra còn có thư mục spiders nhưng không chứa gì ngoài file __init__.py.
Trong phần này chúng ta sẽ chủ yếu làm việc với items.py
và những gì trong thư mục spiders
.
Định nghĩa Item
Mở file items.py ra. Chúng ta sẽ thấy Scrapy đã tạo một ít code bên trong, mà trong đó là đoạn import scrapy
và phần định nghĩa class BdsItem
trống rỗng và một số comment.
# -*- coding: utf-8 -*- # Define here the models for your scraped items # # See documentation in: # https://docs.scrapy.org/en/latest/topics/items.html import scrapy class ExItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() pass
Chúng ta sẽ sửa lại class này bằng cách thêm vào một thuộc tính như sau:
import scrapy from scrapy.item import Item, Field class ExItem(scrapy.Item): title = Field()
Chúng ta định nghĩa một thuộc tính tên là title
thuộc lớp Field
, được khởi tạo bằng cách gọi Field()
.
Spider
Spider có thể coi là các đoạn code làm công việc cào dữ liệu, làm tất cả các công đoạn trong tiến trình UR2IM. Thông thường chúng ta viết 1 spider cho 1 trang trong website hoặc một phần của trang nếu trang đó quá lớn.
Chúng ta tạo một spider bằng lệnh scrapy genspider <tên_spider>
. Ví dụ:
D:>ex scrapy genspider basic web Created spidder 'basic' using template 'basic' in module: bds.spiders.basic
Đoạn code trên sẽ tạo ra một file có tên basic.py
trong thư mục ex/spiders
.
# -*- coding: utf-8 -*- import scrapy class BasicSpider(scrapy.Spider): name = 'basic' allowed_domains = ['web'] start_urls = ['http://web/'] def parse(self, response): pass
Bên trong file này có định nghĩa lớp BasicSpider
, lớp này dùng mẫu “Basic”, và bị giới hạn chỉ cào dữ liệu trên các websites. Scrapy 1.8.0 có tất cả 4 mẫu Spider là basic
, crawl
, csvfeed
và xmlfeed
. Bạn có thể xem danh sách các mẫu bằng cách chạy lệnh scrapy genspider -l
. Chúng ta sẽ tìm hiểu thêm về các loại mẫu sau. Lớp BasicSpider
này thừa kế từ lớp Spider từ gói scrapy.Spider
, có một số thuộc tính và phương thức parse()
, phương thức này nhận vào 2 tham số, self
và response
, và tham số response
phải truyền vào ở đây chính là đối tượng response
mà chúng ta sử dụng trong Scrapy shell.
Bây giờ chúng ta sửa lại file này như sau:
# -*- coding: utf-8 -*- import scrapy class BasicSpider(scrapy.Spider): name = "basic" allowed_domains = ["web"] start_urls = ( 'https://example.com', ) def parse(self, response): self.log("Title: %s" % response.xpath( '//div//h1/text()').extract())
Đầu tiên chúng ta sửa lại mảng start_urls
bằng cách đưa vào đường link dẫn tới trang http://example.com
Bên trong phương thức parse()
. Chúng ta gọi phương thức log(),
phương thức này có tác dụng in chuỗi ra màn hình (console) giống như print().
Bên trong phương thức này chúng ta truyền chuỗi và gọi đoạn code lấy giá trị của element <h1>
theo XPath như trong các bài trước.
Bây giờ chung ta có thể chạy đoạn code spider này với lệnh scrapy crawl
như sau:
D:/ex>scrapy crawl basic ... ... INFO: Scrapy 1.8.0 started (bot: bds) ... INFO: Spider opened ... DEBGUG: Crawled (200) <GET http://example.com> (referer: None) DEBUG: Title: ['Example Domain'] ... INFO: Spider closed (finished)
Scrapy sẽ khởi chạy và gọi phương thức parse()
của lớp BasicSpider. Màn hình sẽ in ra rất nhiều dòng output, chúng ta chưa cần quan tâm về chúng. Tuy nhiên nếu bạn tìm thấy các đoạn INFO và DEBUG giống như trên thì Spider của bạn đã chạy thành công.
Chúng ta có thể chạy Spider bằng lệnh khác là scrapy parse
như sau:
D:/ex/scrapy parse --spider=basic http://example.com
Trong đoạn code trên, chúng ta truyền vào tham số --spider
là basic, để Scrapy biết là nó sẽ chạy Spider bên trong file basic.py,
tham số tiếp theo là URL mà nó sẽ cào dữ liệu.
Lưu lại dữ liệu vào Item
Chúng ta sửa lại file basic.py
như sau:
# -*- coding: utf-8 -*- import scrapy from ex.items import ExItem class BasicSpider(scrapy.Spider): name = "basic" allowed_domains = ["web"] start_urls = ( 'https://example.com', ) def parse(self, response): item = ExItem() item["Title"] = response.xpath( '//div//h1/text()').extract() return item
Ở đây chúng ta import lớp ExItem
được định nghĩa trong file items.py
trước đó. Sau đó chúng ta khởi tạo đối tượng item
từ lớp này và gán giá trị cho thuộc tính Title
là những gì được trả về từ việc gọi response().xpath().extract()
. Cuối cùng là return đối tượng này thay vì gọi phương thức response.log()
như trước.
Chúng ta chạy lại lệnh scrapy crawl basic
như lúc trước:
D:/ex>scrapy crawl basic ... DEBUG: Scraped from <200 https://example.com> {'Title': ['Example Domain']} ...
Ngoài những dòng output khác, thì những dòng log đã biến mất, thay vào đó là Scrapy in ra một object data chứa key là 'Title'
với giá trị là mảng ['Example Domain']