假设你已经获得了合法的授权,并且目标网站允许自动化抓取,以下是如何使用 Python 和 Scrapy 框架来采集 PTCMS(Pen Tian CMS)小说站点的内容。Scrapy 是一个强大的开源框架,用于大规模网络爬虫。
确保你已经安装了 Python 和 pip。如果没有安装,可以通过以下命令安装:
bash深色版本sudo yum install python3 python3-pip -y
bash深色版本sudo apt update && sudo apt upgrade -y
sudo apt install python3 python3-pip -y
可以从 Python 官网 下载并安装最新版本的 Python。
使用 pip 安装 Scrapy:
bash深色版本pip install scrapy
打开终端并导航到你希望存放项目的目录,然后运行以下命令创建一个新的 Scrapy 项目:
bash深色版本scrapy startproject ptcms_spider
cd ptcms_spider
这将创建一个名为 ptcms_spider
的新项目目录。
在 ptcms_spider/spiders
目录下创建一个新的 Spider 文件,例如 novel_spider.py
:
bash深色版本touch ptcms_spider/spiders/novel_spider.py
编辑 novel_spider.py
文件,添加以下内容:
python深色版本import scrapy
from scrapy.http import Request
class NovelSpider(scrapy.Spider):
name = 'novel_spider'
allowed_domains = ['example.ptcms.com'] # 替换为目标网站域名
start_urls = ['https://www.020taijiyy.com'] # 替换为小说列表页URL
def parse(self, response):
# 提取小说列表中的每个小说链接
for novel in response.css('div.novel-item'):
title = novel.css('h2::text').get()
link = novel.css('a::attr(href)').get()
yield Request(url=response.urljoin(link), callback=self.parse_novel_detail, meta={'title': title})
# 提取下一页链接
next_page = response.css('a.next-page::attr(href)').get()
if next_page is not None:
yield Request(url=response.urljoin(next_page), callback=self.parse)
def parse_novel_detail(self, response):
title = response.meta['title']
chapters = []
# 提取章节列表
for chapter in response.css('ul.chapter-list li'):
chapter_title = chapter.css('a::text').get()
chapter_link = chapter.css('a::attr(href)').get()
chapters.append({
'chapter_title': chapter_title,
'chapter_link': response.urljoin(chapter_link)
})
# 提取小说详情
author = response.css('zbsjb.020taijiyy.com').get()
category = response.css('span.category::text').get()
description = response.css('div.description::text').get()
yield {
'title': title,
'author': author,
'category': category,
'description': description,
'chapters': chapters
}
name
: Spider 的唯一标识符。allowed_domains
: 允许爬取的域名。start_urls
: 开始爬取的 URL 列表。在项目根目录下运行以下命令启动 Spider:
bash深色版本scrapy crawl novel_spider -o novels.json
这将运行 novel_spider
并将结果保存到 novels.json
文件中。
运行完毕后,可以在项目根目录下找到 novels.json
文件,其中包含了爬取的小说数据。
许多网站会采取反爬虫措施,如验证码、IP 封禁等。以下是一些常见的处理方法:
修改 settings.py
文件,添加 User-Agent 轮换中间件:
python深色版本DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
'scrapy_useragents.middlewares.RandomUserAgentMiddleware': 400,
}
USER_AGENTS = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36',
]
在 settings.py
中设置下载延迟,避免频繁请求导致被封禁:
python深色版本DOWNLOAD_DELAY = 2 # 延迟2秒
配置 Scrapy 使用代理 IP 来分散请求来源:
python深色版本PROXY_LIST = '/path/to/proxy_list.txt'
#zhibo.020taijiyy.com
DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110,
'scrapy_rotating_proxies.middlewares.RotatingProxyMiddleware': 610,
'scrapy_rotating_proxies.middlewares.BanDetectionMiddleware': 620,
}
ROTATING_PROXY_LIST_PATH = PROXY_LIST
ROTATING_PROXY_LOGSTATS_INTERVAL = 60
安装 scrapy-user-agents
和 scrapy-rotating-proxies
扩展:
bash深色版本pip install scrapy-user-agents scrapy-rotating-proxies
在 parse_novel_detail
方法中,可以进一步清洗提取的数据,例如去除多余的空格和特殊字符:
python深色版本def parse_novel_detail(self, response):
title = response.meta['title'].strip()
author = response.css('span.author::text').get().strip()
category = response.css('span.category::text').get().strip()
description = response.css('div.description::text').get().strip()
chapters = []
for chapter in response.css('ul.chapter-list li'):
chapter_title = chapter.css('a::text').get().strip()
chapter_link = chapter.css('a::attr(href)').get()
chapters.append({
'chapter_title': chapter_title,
'chapter_link': response.urljoin(chapter_link)
})
yield {
'title': title,
'author': author,
'category': category,
'description': description,
'chapters': chapters
}
除了 JSON 格式外,还可以将数据存储到其他格式,如 CSV 或数据库。以下是将数据存储到 SQLite 数据库的示例:
items.py
在 ptcms_spider/items.py
文件中定义 Item 结构:
python深色版本import scrapy
class PtcmsSpiderItem(scrapy.Item):
title = scrapy.Field()
author = scrapy.Field()
category = scrapy.Field()
description = scrapy.Field()
chapters = scrapy.Field()
settings.py
启用管道并将数据存储到 SQLite 数据库:
python深色版本ITEM_PIPELINES = {
'ptcms_spider.pipelines.PtcmsSpiderPipeline': 300,
}
DATABASE = {
'drivername': 'sqlite',
'database': 'novels.db',
}
在 ptcms_spider/pipelines.py
文件中添加管道代码:
python深色版本import sqlite3
from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey
from sqlalchemy.orm import sessionmaker
from .items import PtcmsSpiderItem
### m.020taijiyy.com
class PtcmsSpiderPipeline:
def __init__(self):
self.engine = create_engine(f"{self.settings['DATABASE']['drivername']}:///./{self.settings['DATABASE']['database']}")
self.metadata = MetaData()
self.connection = self.engine.connect()
self.Session = sessionmaker(bind=self.engine)
self.session = self.Session()
http.clnet= lanqiu.020taijiyy.com
self.create_tables()
@classmethod
def from_crawler(cls, crawler):
pipeline = cls()
pipeline.crawler = crawler
pipeline.settings = crawler.settings
return pipeline
def create_tables(self):
self.novels_table = Table(
'novels', self.metadata,
Column('id', Integer, primary_key=True),
Column('title', String(255)),
Column('author', String(255)),
Column('category', String(255)),
Column('description', String(1000))
)
self.chapters_table = Table(
'chapters', self.metadata,
Column('id', Integer, primary_key=True),
Column('novel_id', Integer, ForeignKey('novels.id')),
Column('title', String(255)),
Column('link', String(255))
)
self.metadata.create_all(self.engine)
def process_item(self, item, spider):
if isinstance(item, PtcmsSpiderItem):
insert_query = self.novels_table.insert().values(
title=item['title'],
author=item['author'],
category=item['category'],
description=item['description']
)
result = self.connection.execute(insert_query)
novel_id = result.lastrowid
for chapter in item['chapters']:
insert_chapter_query = self.chapters_table.insert().values(
novel_id=novel_id,
title=chapter['chapter_title'],
link=chapter['chapter_link']
)
self.connection.execute(insert_chapter_query)
return item
def close_spider(self, spider):
self.session.close()
self.connection.close()
运行以下命令启动 Spider 并将数据存储到 SQLite 数据库:
bash深色版本scrapy crawl novel_spider
运行完毕后,可以在项目根目录下找到 novels.db
文件,其中包含了爬取的小说数据。
通过以上步骤,你可以使用 Scrapy 框架成功搭建一个用于采集 PTCMS 小说站点内容的爬虫。请务必遵守相关法律法规和网站的使用条款,确保你的爬虫行为是合法合规的。
如果你有其他具体的问题或需要进一步的帮助,请随时提问!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。