Scrapy Framework
Scrapy is a Python application framework for crawling websites and extracting structured data. It can be used for data mining, information processing, historical data storage, and more. It was originally designed for web scraping but can also be used to extract data from APIs (Web Services). Scrapy also supports advanced scraping scenarios such as authentication, content analysis, deduplication, and distributed crawling.
Reference: Scrapy documentation
Installation
Scrapy requires Python 3.6+ (CPython or PyPy 7.2.0+).
Linux:
pip install scrapyWindows:
pip install wheel
# Download the Twisted wheel for your Python version from:
# http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
pip install Twisted-17.1.0-cp35-cp35m-win_amd64.whl
pip install pywin32
pip install scrapyBasic Usage
# Create a new Scrapy project
scrapy startproject tutorial
# Navigate into the project directory
cd tutorial
# Generate a spider (must be created inside the spiders/ folder)
scrapy genspider spiderName www.example.com
# Run the spider
scrapy crawl spiderNameRecommended settings.py Configuration
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36'
ROBOTSTXT_OBEY = False # disable robots.txt compliance
LOG_LEVEL = 'ERROR' # suppress verbose logs
CONCURRENT_REQUESTS = 32Project Structure
myproject/
├── scrapy.cfg
└── myproject/
├── items.py # data model definitions
├── middlewares.py # spider and downloader middlewares
├── pipelines.py # data storage pipeline
├── settings.py # global configuration
├── __init__.py
└── spiders/
├── __init__.py
└── myspider.py # the actual spiderSpider File Structure (spiders/bili.py)
import scrapy
class BiliSpider(scrapy.Spider):
name = 'bili' # unique identifier for this spider
# allowed_domains = ['search.bilibili.com'] # restrict to this domain
start_urls = [
'https://search.bilibili.com/all?keyword=dance',
]
def parse(self, response):
# response is a Scrapy Response object
li_list = response.xpath('//*[@id="all-list"]/div[1]/div[2]/ul/li')
all_data = []
for item in li_list:
title = item.xpath('./a/@title')[0].extract()
video_url = 'https:' + item.xpath('./a/@href')[0].extract()
all_data.append({'title': title, 'url': video_url})
print({'title': title, 'url': video_url})
return all_dataData Persistence
Method 1: Command-line Output
The simplest way — saves the parse() method’s return value directly to a file:
scrapy crawl spiderName -o output.json
scrapy crawl spiderName -o output.csvSupported formats: json, jsonlines, jl, csv, xml, marshal, pickle.
Pros: simple and fast. Cons: limited flexibility — only saves what parse() returns.
Method 2: Pipeline-based Persistence
The recommended approach for production use:
The number (300, 301, etc.) is the pipeline priority — lower numbers run first. Each pipeline’s process_item must return item to pass the item to the next pipeline in the chain.
When to use multiple pipelines: when you want to store a copy of the data in multiple destinations (e.g., both a JSON file and a MySQL database), define one pipeline class per storage target.