Professional Documents
Culture Documents
FILE 20210217 182321 Dlscrib - Com PDF Crawl Data With Scrapy Public Draft DL
FILE 20210217 182321 Dlscrib - Com PDF Crawl Data With Scrapy Public Draft DL
FILE 20210217 182321 Dlscrib - Com PDF Crawl Data With Scrapy Public Draft DL
1
License
Contributors
No. Name Email
2
Mục lục
License 2
Contributors 2
1. Scrapy Architecture 6
1.1 Thành phần 6
1.2 Luồng dữ liệu 6
5. Pipeline 15
Duplicates filter 15
Write items to a JSON file 15
Price validation and dropping items with no prices 15
Clean whitespace and HTML 16
6. Extractor, Spider 16
Duyệt all page 16
Thêm thông tin vào callback functions 17
XPath pattern 17
XPath Tips from the Web Scraping Trenches 18
Config ItemLoad default: extract first and strip 19
Các thư viện Extractor 20
7. Downloader 21
Cấu hình và sử dụng proxy 21
3
Working with http proxy 21
Scrapy Download images 23
8. Scrapy setting 23
ITEM_PIPELINES 23
DownloaderStats 24
Scrapy debug 26
Scrapy caching 26
Scrapy-fake-useragent 29
By-pass anti-crawler 32
Django-dynamic-scraper (DDS) 39
Requirements: 39
Documents 40
SETUP: 40
1. Install docker, compose 40
2. Run docker django-dynamic-scraper 40
3. Defining the object to be scraped 40
4
4. run crawl data 41
5. run schedule crawl: 41
5
1. Scrapy Architecture
http://doc.scrapy.org/en/latest/topics/architecture.html
6
Bước 9: kiểm tra Scheduler còn R
equest?
● Đúng: quay lại Bước 2.
● Sai: kết thúc.
Install Scrapy
# install virtualenv
sudo pip install virtualenv
7
Các bước chính trong tutorial:
Tạo một Scrapy project:
scrapy startproject tutorial
Chúng ta định nghĩa một danh sách khởi tạo của URLs để download, cách follow links, và
cách parse nội dung của pages để trích xuất items.
Để tạo một spider, chúng ta tạo một subclass scrapy.Spider và định nghĩa một số thuộc tính
● name: định danh spider và nó là duy nhất
● start_urls: một danh sách urls cho spider bắt đầu thực hiện crawl. Các trang được
download đầu tiên sẽ bắt đầu từ đây, còn lại sẽ được tạo từ dữ liệu đã được lấy về
● parse(): một phương thức sẽ được gọi với một đối tượng Response đã được
download của mỗi start urls. The response sẽ được truyền tới phương thức như là
tham số đầu tiên và duy nhất của phương thức. Phương thức này có trách nhiệm
phân tích response data và trích xuất scraped data (như là scraped items ) và nhiều
url để follow (như là Request object)
Tạo một spider trong thư mục tutorial/spiders.
8
3. Crawling
Tới thư mục gốc của project và chạy lệnh:
scrapy crawl dmoz // dmoz là tên của scrapy (name)
=> Quá trình thực hiện:
- Scrapy tạo scrapy.Request cho mỗi URL trong list start_urls của spider và gán chúng
phương thức parse được gọi bởi callback function của chúng.
- Các Request được lập lịch rồi thực thi và trả về scrapy.http.Response object, sau đó được
đưa trở lại spider thông qua phương thức parse().
4. Extracting Items
Introduction to Selectors
- Sử dụng cơ chế dựa trên Xpath hoặc biểu thức CSS gọi là Scrapy Selector.
Note: XPath mạnh mẽ hơn CSS
- Scrapy cung cấp class Selector và một số quy ước, shortcut để làm việc với biểu thức
xpath và css
- Selector object đại diện các nodes ở trong một document có cấu trúc. Vì thế đầu tiên khởi
tạo một selector gắn với root node hoặc toàn bộ tài liệu
- Selector có 4 phương thức cơ bản:
1. xpath(): trả về danh sách các selectors, mỗi cái đại diện cho một node đã được chọn
bằng tham số biểu thức xpath truyền vào.
2. css(): trả về danh sách các selectors, mỗi cái đại diện cho một node đã được chọn
bằng tham số biểu thức css truyền vào.
3. extract(): trả về một list unicode string với dữ liệu được chọn -> c ó thể dùng
extract_first() để lấy 1 phần tử đầu tiên
4. re(): trả về danh sách unicode string đã được trích xuất bằng applying tham số biểu
thức chính quy truyền vào.
Note: response object có thuộc tính selector là instance của Selector class. Chúng ta có thể
query bằng cách: response.selector.xpath() or response.selector.css()
hoặc sử dụng shortcut: response.xpath() or r esponse.css()
Following links
url = response.urljoin(href.extract())
yield scrapy.Request(url, callback=self.parse_dir_contents)
9
5. Storing the scraped data (lưu trữ kết quả sau khi crawl)
Dùng lệnh:
scrapy crawl dmoz -o items.json
Lấy dữ liệu
[x] How to extract data?
[] Thư viện các mẫu extract, các ví dụ extract.
1. Scrapy:
- re-extractor (ví dụ như dùng caching)
- download continue
- re-visit for update.
- Xử lí vấn đề caching. Thử nghiệm.
10
2. Monitoring scrapy, status, log: Tìm cách lấy các thông tin về tình trạng crawler, như
Scrapy stats nhưng ở dạng realtime. Mục đích là để biết tình trạng crawler như thế nào.
3. Using scrapy with Docker: Đóng gói scrapy vào docker. Chạy trong docker
Python Conventions
https://www.python.org/dev/peps/pep-0008/
http://docs.python-guide.org/en/latest/writing/style/
Xpath
Tool để thử xpath:
https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl?
utm_source=chrome-app-launcher-info-dialog
Docker
Install docker and docker-compose
# install docker
wget -qO- https://get.docker.com/ | sh
sudo usermod -a -G docker `whoami`
# install docker-compose
sudo wget
https://github.com/docker/compose/releases/download/1.9.0/docker-compose-`una
me -s`-`uname -m` -O /usr/local/bin/docker-compose
Tham khảo:
https://github.com/tranhuucuong91/docker-training
Chú ý: Nếu crawl dữ liệu lớn hoặc những trang kiểm duyệt chặt cần xử dụng proxy để tránh
bị ban IP
11
4. Store into database
mongodb
https://hub.docker.com/_/mongo/
version: "2"
services:
mongodb:
image: mongo:3.2
ports:
- "27017:27017"
volumes:
- ./mongodb-data/:/data/db
# hostname: mongodb
# domainname: coclab.lan
cpu_shares: 512 # 0.5 CPU
mem_limit: 536870912 # 512 MB RAM
# privileged: true
# restart: always
# stdin_open: true
# tty: true
MongoDB to MySQL
Database == Database
Collection == Table
Document == Row
Đọc thêm: Why MongoDB Is a Bad Choice for Storing Our Scraped Data
https://blog.scrapinghub.com/2013/05/13/mongo-bad-for-scraped-data/
1. Locking
2. Poor space efficiency
3. Too Many Databases
4. Ordered data
12
5. Skip + Limit Queries are slow
6. Restrictions
7. Impossible to keep the working set in memory
8. Data that should be good, ends up bad!
@classmethod
def from_crawler(cls, crawler):
return cls(
mongo_uri=crawler.settings.get('MONGO_URI'),
mongo_db=crawler.settings.get('MONGO_DATABASE', 'items')
)
Export/Import MongoDB
13
Import to mongodb:
#copy gzip file from local to container
docker cp /path/to/file container_id:/root
#restore
mongorestore --gzip --archive=/root/crawler.2016-04-18_07-40-11.gz
--db crawler
Install mysqlclient
sudo apt-get install -y libmysqlclient-dev
sudo pip2 install mysqlclient
sudo pip2 install sqlalchemy
MySQL Command:
# Login
mysql -u username -p
# import:
> use name
> source import.sql
Pipeline điều khiển quá trình store. Models xử lý tạo bảng db.
_init_ : kết nối và khởi tạo bảng dữ liệu,
hàm xử lý việc lưu dữ liệu vào bảng (sessionmaker)
process: tham số là item và spider. dữ liệu được crawl bởi spider được đưa vào item, sau
đó được session đưa vào lưu trữ trong db
14
5. Pipeline
Duplicates filter
class DuplicatesPipeline(object):
def __init__(self):
self.ids_seen = set()
class JsonWriterPipeline(object):
def __init__(self):
self.file = open('items.jl', 'wb')
class PricePipeline(object):
vat_factor = 1.15
15
if item['price']:
if item['price_excludes_vat']:
item['price'] = item['price'] * self.vat_factor
return item
else:
raise DropItem("Missing price in %s" % item)
# spider specific
if spider.name == "techmeme":
item['blurb'] = item['blurb'].replace(' — ',
'').strip()
return item
6. Extractor, Spider
Duyệt all page
Cần xác định rõ cấp độ của page
● start_urls (cấp 1)
● trong Parse dẫn link đến page cấp 2 -> đây là page cần duyệt hết các page con trong
đó
● parse_next_page: crawl dữ liệu
yield item
16
next_page = response.css("ul.navigation > li.next-page > a::attr('href')")
if next_page:
url = response.urljoin(next_page[0].extract())
yield scrapy.Request(url, self.parse_articles_follow_next_page)
Note: để test kết quả trả về khi dùng các selector, ta dùng scrapy shell
cú pháp: scrapy shell [url]
https://doc.scrapy.org/en/latest/topics/shell.html#topics-shell
Tình huống: khi duyệt các category -> ... -> website công ty -> lấy dữ liệu về công ty
Vấn đề: muốn lưu thông tin category của công ty
-> Giải pháp: truyền thêm thông tin vào callback functions.
XPath pattern
//p[contains(string(),'Address:')]
17
vietnamese_title //p[contains(string(),'Vietnamese
Title:')]
english_title //p[contains(string(),'English Title:')]
address //p[contains(string(), 'Address:') or
contains(string(), 'Địa chỉ:') or contains(string(), 'Trụ sở chính:')]
province //p[contains(string(),'Province:')]
director //p[contains(string(),'Director:')]
tel //p[contains(string(),'Tel:') or
contains(string(),'Điện thoại:')]
fax //p[contains(string(),'Fax:')]
email //p[contains(string(),'Email:')]
main_business //p[contains(string(),'Main Business:')]
business //p[(contains(string(),'Business:') and
not(contains(string(),'Main Business'))) or contains(string(),'Ngành nghề
kinh doanh:')]
website //p[contains(string(),'Website:')]
company_title
//p[contains(string(),'Vietnamese Title:')]
Avoid using contains(.//text(), ‘search text’) in your XPath conditions. Use contains(.,
‘search text’) instead.
GOOD:
18
2 [u'Page']
BAD:
(//node)[1] selects all the nodes in the document, and then gets only the first of them.
>>> sel.css(".content").extract()
[u'<p class="content text-wrap">Some content</p>']
>>> sel.css('.content').xpath('@class').extract()
[u'content text-wrap']
1 //*[not(self::script or self::style)]/text()[normalize-space(.)]
This excludes the content from script and style tags and also skip whitespace-only text nodes.
Source: http://stackoverflow.com/a/19350897/2572383
http://stackoverflow.com/questions/17000640/scrapy-why-extracted-strings-are-in-this-format
There's a nice solution to this using I tem Loaders. Item Loaders are objects that get data
from responses, process the data and build Items for you. Here's an example of an Item
Loader that will strip the strings and return the first value that matches the XPath, if any:
19
class MyItemLoader(XPathItemLoader):
default_item_class = MyItem
default_output_processor = TakeFirst()
loader = MyItemLoader(response=response)
loader.add_xpath('desc', 'a/text()')
return loader.load_item()
http://jeroenjanssens.com/2013/08/31/extracting-text-from-html-with-reporter.html
2. python-boilerpipe
https://github.com/misja/python-boilerpipe
Python interface to Boilerpipe, Boilerplate Removal and Fulltext Extraction from HTML pages
3. python-goose
https://github.com/grangier/python-goose
Html Content / Article Extractor, web scrapping lib in Python
pip2 install: goose-extractor
https://github.com/codelucas/newspaper
pip3 install newspaper3k
Ví dụ:
https://blog.openshift.com/day-16-goose-extractor-an-article-extractor-that-just-works/
https://github.com/shekhargulati/day16-goose-extractor-demo
http://vietnamnet.vn/vn/thoi-su/du-bao-thoi-tiet-hom-nay-6-12-ha-noi-ret-14-do-mien-trung-m
ua-cuc-lon-344734.html
20
7. Downloader
Cấu hình và sử dụng proxy
http://doc.scrapy.org/en/latest/topics/downloader-middleware.html
https://rohitnarurkar.wordpress.com/2013/10/29/scrapy-working-with-a-proxy-network/
# Importing base64 library because we'll need it ONLY in case if the proxy we
are going to use requires authentication
import base64
http://wayback.archive.org/web/20150828053704/http://blog.michaelyin.info/2014/02/19/scra
py-socket-proxy/
21
When crawling infos from some website like google shop, it will detect the source ip and restrict
some service to some specific ip address, however, scrapy framework can handle this situation
by making the request through proxy.
The scrapy has provided HttpProxyMiddleware to support http proxy, if you want to make your
web crawler to go through proxy, the first thing you need to do is modify your setting file just like
this
http://stackoverflow.com/questions/19446536/proxy-ip-for-scrapy-framework
Until now i am using middleware in Scrapy to manually rotate ip from free proxy ip list
available of various websites like this
https://pypi.python.org/pypi/proxylist
pl = ProxyList()
pl.load_file('/web/proxy.txt')
pl.random()
pl.random().address()
# '1.1.1.1:8085'
22
Scrapy Download images
http://doc.scrapy.org/en/0.24/topics/images.html
8. Scrapy setting
http://doc.scrapy.org/en/latest/topics/settings.html
ITEM_PIPELINES
Default: {}
A dict containing the item pipelines to use, and their orders. The dict is empty by
default order values are arbitrary but it’s customary to define them in the 0-1000
range.
ITEM_PIPELINES = {
'mybot.pipelines.validate.ValidateMyItem': 300,
'mybot.pipelines.validate.StoreMyItem': 800,
}
23
DownloaderStats
Middleware lưu trữ số liệu thống kê của tất cả các yêu cầu, phản ứng và các ngoại
lệ đó đi qua nó.
'scrapy.downloadermiddleware.stats.DownloaderStats': None,
http://doc.scrapy.org/en/latest/topics/downloader-middleware.html#module-scrapy.downloadermi
ddlewares.stats
During my crawling, some pages return a response with partial html body and status 200,
after I compare the response body with the one I open in browser, the former one miss
something. How can I catch this unexpected partial response body case in spider or in
download middleware?
Answer:
Its not partial content as such. The rest of the content is dynamically loaded by a
Javacript AJAX call.
To debug what content is being sent as response for a particular request, use Scrapy's
open_in_browser() function.
There's another thread on How to extract dynamic content from websites that are using
AJAX ?. Refer this for a workaround.
Để xử lí những website sử dụng AJAX, có cách dùng selenium để lấy nội dung website,
giống như cách duyệt web thông thường: browser render dữ liệu
với cách này thì tốc độ crawler sẽ chậm hơn rất nhiều
Dùng selenium thì có webdriver là Firefox, sẽ yêu cầu giao diện đồ họa. Muốn chạy trên
server không có giao diện đồ họa thì dùng PhantomJS.
24
Headless with PhantomJS: sử dụng PhantomJS cho automation testing, crawler
Selenium with headless phantomjs webdriver
https://realpython.com/blog/python/headless-selenium-testing-with-python-and-phantomjs/
1. Setup
2. Example
3. Benchmarking
https://dzone.com/articles/python-testing-phantomjs
Element not found in the cache - perhaps the page has changed since it was looked up
-> cần phải tìm lại element sau khi reload trang
Web elements you stored before clicking on login button will not be present in cache after
login because of page refresh or page changes. You need to again store these web
elements in order to make them available again under cache. I have modified your code a bit
which might help:
element = driver.find_element_by_name('Years')
all_options = element.find_elements_by_tag_name('option')
25
option = all_options[index]
http://www.thecodeknight.com/post_categories/search/posts/scrapy_python
Scrapy debug
http://doc.scrapy.org/en/latest/topics/debug.html#open-in-browser
Scrapy caching
http://doc.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-storage-fs
HTTPCACHE_ENABLED = True
HTTPCACHE_GZIP = True
HTTPCACHE_EXPIRATION_SECS = 30 * 24 * 60 * 60
26
Scrapy revisit for update:
http://stackoverflow.com/questions/23950184/avoid-scrapy-revisit-on-a-different-run
pipelines.py
from mybot.utils import connect_url_database
class DedupPipeline(object):
def __init__(self):
self.db = connect_url_database()
middlewares.py
from scrapy import log
from scrapy.exceptions import IgnoreRequest
from mybot.utils import connect_url_database
class DedupMiddleware(object):
def __init__(self):
self.db = connect_url_database()
settings.py
ITEM_PIPELINES = {
'mybot.pipelines.DedupPipeline': 0
}
DOWNLOADER_MIDDLEWARES = {
'mybot.middlewares.DedupMiddleware': 0
}
Sometimes, for big sites, it’s desirable to pause crawls and be able to resume them later.
27
How to use it
To start a spider with persistence supported enabled, run it like this:
scrapy crawl somespider -s JOBDIR=crawls/somespider-1
Then, you can stop the spider safely at any time (by pressing Ctrl-C or sending a
signal), and resume it later by issuing the same command:
scrapy crawl somespider -s JOBDIR=crawls/somespider-1
class CustomPipeline(object)
28
Scrapy-fake-useragent
Random User-Agent middleware based on f ake-useragent. It picks up User-Agent strings
based on usage statistics from a real world database.
Configuration
In Scrapy >=1.0:
DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
'scrapy_fake_useragent.middleware.RandomUserAgentMiddleware': 400,
}
We often have to write spiders that need to login to sites, in order to scrape data from them.
Our customers provide us with the site, username and password, and we do the rest.
The classic way to approach this problem is:
1. launch a browser, go to site and search for the login page
2. inspect the source code of the page to find out:
1. which one is the login form (a page can have many forms, but usually one of
them is the login form)
2. which are the field names used for username and password (these could vary
a lot)
3. if there are other fields that must be submitted (like an authentication token)
29
3. write the Scrapy spider to replicate the form submission using FormRequest (here is
an example)
Being fans of automation, we figured we could write some code to automate point 2 (which is
actually the most time-consuming) and the result is loginform, a library to automatically fill
login forms given the login page, username and password.
Here is the code of a simple spider that would use loginform to login to sites automatically:
In addition to being open source, loginform code is very simple and easy to hack (check the
README on Github for more details). It also contains a collection of HTML samples to keep
the library well-tested, and a convenient tool to manage them. Even with the simple code so
far, we have seen accuracy rates of 95% in our tests. We encourage everyone with similar
needs to give it a try, provide feedback and contribute patches.
https://blog.scrapinghub.com/2016/05/11/monkeylearn-addon-retail-classifier-tutorial/
My script:
1. My spider has a start url of searchpage_url
2. The searchpage is requested by parse() and the search form response gets passed
to search_generator()
3. search_generator() then yields lots of search requests using FormRequest and the
search form response.
4. Each of those FormRequests, and subsequent child requests need to have it's own
session, so needs to have it's own individual cookiejar and it's own session cookie.
=> Solution
30
Multiple cookie sessions per spider
http://doc.scrapy.org/en/latest/topics/downloader-middleware.html#std:reqmeta-cookiejar
There is support for keeping multiple cookie sessions per spider by using the cookiejar
Request meta key. By default it uses a single cookie jar (session), but you can pass an
identifier to use different ones.
For example:
for i, url in enumerate(urls):
yield scrapy.Request("http://www.example.com", meta={'cookiejar': i},
callback=self.parse_page)
Keep in mind that the cookiejar meta key is not “sticky”. You need to keep passing it along
on subsequent requests. For example:
def start_requests(self):
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36'}
for i,url in enumerate(self.start_urls):
yield Request(url,cookies={'over18':'1'}, callback=self.parse_item,
headers=headers)
Don't know what's wrong with CrawlSpider but Spider could work anyway.
# encoding: utf-8
import scrapy
class MySpider(scrapy.Spider):
name = 'redditscraper'
allowed_domains = ['reddit.com', 'imgur.com']
start_urls = ['https://www.reddit.com/r/nsfw']
31
wrapper for scrapy.request
"""
request = scrapy.Request(url=url, callback=callback)
request.cookies['over18'] = 1
request.headers['User-Agent'] = (
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,
'
'like Gecko) Chrome/45.0.2454.85 Safari/537.36')
return request
def start_requests(self):
for i, url in enumerate(self.start_urls):
yield self.request(url, self.parse_item)
By-pass anti-crawler
- Một số cách tinh chỉnh setting cho Scrapy:
+ Tăng delay time
+ Giảm concurrent request
+ Dùng proxy
+ Một số trick khác - tùy trang (ajax....)
- https://learn.scrapehero.com/how-to-prevent-getting-blacklisted-while-scraping/
- http://doc.scrapy.org/en/latest/topics/practices.html#avoiding-getting-banned
32
Kinh nghiệm thực tế
Alibaba redirect, yêu cầu đăng nhập
-> có thể thực hiện bước đăng nhập.
Xử lí products list
Ví dụ: http://www.alibaba.com/Agricultural-Growing-Media_pid144
response.xpath('//div[@class="cbrand ellipsis"]')
33
response.xpath('//div[@class="stitle util-ellipsis"]')
-> null. Không lấy được dữ liệu.
Ví dụ:
wget http://www.alibaba.com/catalogs/products/CID144/2
page.setPageData({"baseServer":"//www.alibaba.com","isForbiddenSel
l":false,"isForbidden":false,"clearAllHref":"//www.alibaba.com/cat
alogs/products/CID144","quotationSupplierNum":250375,"allCategory"
:null,"searchbarFixed":
Tách phần json, được dữ liệu json của 2 trang như sau.
http://pastebin.com/TBxYswGD
http://pastebin.com/ZFEMcuST
Có thể dùng trang sau để đọc file json, có vẻ đẹp hơn trang em đang dùng:
http://www.jsoneditoronline.org/
34
Ví dụ:
json_data =
response.xpath('string(//body)').re(r'page.setPageData\((.*?\})\);')[0]
# tiếp tục xử lí json
Hoặc:
1. Dùng regular expression, extract chính xác dữ liệu mong muốn.
Ví dụ:
Pattern:
"supplierHref":"http://dfl-vermiculite.en.alibaba.com/company_profile.h
tml#top-nav-bar"
Code extract:
response.xpath('string(//body)').re(r'"supplierHref":"([^#]+)')
Trong bài toán này, chúng ta chọn cách đơn giản là cách 2: dùng regular expression để
extract chính xác phần dữ liệu muốn lấy.
Bài học:
1. Dùng browser thấy được dữ liệu, dùng scrapy không thấy được dữ liệu
-> cần phải lấy dữ liệu raw để phân tích.
2. Cần thấy điểm khác nhau của thứ nhìn thấy trên browser và dữ liệu raw. "Những gì chúng
ta nhìn thấy không như những gì chúng ta nghĩ".
Đây cũng là cách để các website hạn chế việc bị crawl data.
3. Không dùng được xpath thì dùng regular expression. Regular expression là mức cơ bản
nhất, xử lí được hầu hết các vấn đề extract.
Vấn đề next_page:
Có thể giải quyết bằng cách duyệt page theo index tăng dần.
http://www.alibaba.com/catalogs/products/CID144/2
-> next_page: http://www.alibaba.com/catalogs/products/CID144/3
origin_url = 'http://www.alibaba.com/catalogs/products/CID144/2'
url_token = origin_url.split('/')
next_page_url = '/'.join(url_token[:-1] + [str(int(url_token[-1]) + 1)])
print(next_page_url)
35
-> khi nút Next không có thẻ <a>
36
Deploy project scrapy sử dụng ScrapingHub
Source: https://scrapinghub.com/
Scrapinghub là một cloud dựa trên web crawling platform hỗ trợ deloy và scale mà bạn sẽ
không phải lo lắng về server, monitoring, backup và schedule cho project scrapy của mình.
Hỗ trợ nhiều add-ons hỗ trợ việc mở rộng spider của bạn cùng với rotator proxy thông minh
hỗ trợ việc chặn từ các website tăng tốc độ crawl.
Install scrapinghub:
$ pip/pip3 install scrapinghub
Thực hiện login để deploy:
$ shub login
Nhập API key để login (API được lấy tại: https://dash.scrapinghub.com/account/apikey)
Sau khi đăng nhập thông tin sẽ được lưu tại ~ /.scrapinghub.yml
Tiến hành deploy một project lên scrapinghub:
crapy Cloud Projects trên
Tạo một project mới để chứa project của mình tại S
scrapinghub.
Click vào project vừa tạo trên scrapinghub vào mục code & deploy để lấy API project vừa
tạo.
$cd <your project scrapy>
$shub deploy
Tùy chọn cài thêm thư viện khi chạy:
Edit file scrapinghub.yml:
projects:
default: 123
requirements_file: requirements.txt
Nhập API của project sau đó project sẽ được deploy trên scrapinghub.
37
Tiến hành chạy project click vào run chọn tên spider,có vài tùy chọn khi chạy như priority ,
tags, Arguments tùy vào nhu cầu sử dụng.
Bạn chỉ có thể chạy được 1 spider một lúc, cấc cả các lần chạy tiếp theo sẽ được đưa vào
next jobs.
Dữ liệu sẽ được xuất ra csv và được lưu trong data của scrapinghub với thời gian lưu trữ 1
tuần. để lưu lâu hơn bạn sẽ cần phải nâng cấp và trả phí.
38
Lập lịch chạy sprider:
Scrapinghub hỗ trợ lập lịch chạy spider rất dễ sử dụng
Các chức năng free đủ cho bạn deploy và chạy một project với các chức năng và công cụ
hỗ trợ với 1G ram và 1 concurrent crawl. Nếu có nhu cầu bạn có thể nâng cấp để tùy chỉnh
và sử dụng các addons khác.
Django-dynamic-scraper (DDS)
Django-dynamic-scraper use scrapy base on django framework and use admin
django interface create scrapy crawl many website.
Dockerfile: https://github.com/khainguyen95/django-dynamic-scraper
Image: https://hub.docker.com/r/khainguyendinh/django-dynamic-scraper/
Requirements:
● Python 2.7+ or 3.4+
● Django 1.8/1.9
● Scrapy 1.1
● Scrapy-djangoitem 1.1
● Python JSONPath RW 1.4+
● Python future
● scrapyd
● django-celery
39
● django-dynamic-scraper
Documents
Tutorial DDS
Scrapyd-client
DjangoItem in scrapy
SETUP:
40
● CREATE DATABASE news CHARACTER SET utf8 COLLATE utf8_general_ci;
● $cd djangoItem
● create user admin
● python manage.py createsuperuser
● run django server
● python manage.py runserver 0.0.0.0:8000
● show admin django in browser
● http://localhost:8000/admin
● add New Scraped object classes
● add New Scrapers
● add News websites
41
run schedule scrapy:
$python manage.py celeryd -l info -B
--settings=example_project.settings
python manage.py celeryd -l info -B --settings=djangoItem.settings
42
Tài liệu tham khảo
1. Scrapy Documentation. https://doc.scrapy.org/en/latest/
2. Scrapinghub Documentation: h ttps://doc.scrapinghub.com
3. Django Dynamic Scrapy: http://django-dynamic-scraper.readthedocs.io/
TODO: Từ rất nhiều nguồn khác nữa, mỗi phần có link tham khảo. Chúng tôi sẽ sớm cập
nhật đầy đủ tài liệu tham khảo.
43