创建项目
scrapy startproject book # book 为项目名
文件结构
代码实现
mySpider.py
import scrapy
from book.items import BookItem
''' 小说目录第1章
<ul class="cf">
<li data-rid="1">
<a href="//read.qidian.com/chapter/qrqmtYSE7XFmzDX0o03xsg2/LOibR1_EzCTgn4SMoDUcDQ2"
target="_blank"
data-eid="qd_G55"
data-cid="//read.qidian.com/chapter/qrqmtYSE7XFmzDX0o03xsg2/LOibR1_EzCTgn4SMoDUcDQ2"
title="首发时间:2015-08-10 13:56:55 章节字数:1889">
第1章 刘慈欣2018克拉克奖获奖感言
</a>
</li>
'''
''' 小说第1章内容
<div class="read-content j_readContent">
<p> 先生们、女士们,晚上好,<p>
很荣幸获得Clarke Award for Imagination in Service to Society Award。
<p> 这个奖项是对想象力的奖励,而想象力是人类所拥有的一种似乎只应属于神的能力,它存在的意义也远超出我们的想象。
有历史学家说过,人类之所以能够超越地球上的其它物种建立文明,主要是因为他们能够在自己的大脑中创造出现实中不存在的东西。
在未来,当人工智能拥有超过人类的智力时,想象力也许是我们对于它们所拥有的惟一优势。
<p>
</div>
'''
class MySpider(scrapy.Spider):
name = "mySpider" # 爬虫项目名称(开始爬取时会用到)
# 官方文件的解释为包含spider在启动时爬取的url列表,用于定义初始请求。
start_urls = ["https://book.qidian.com/info/1001535146#Catalog"]
def parse_detail(self,response):
# 接收上级已爬取的数据
string = ""
item = response.meta['item']
content = response.xpath("//div[@class='read-content j_readContent']/p/text()").extract()
for i in content:
string = string + i + '\n'
item['content'] = string
yield item
# 运行爬虫后,名为 parse() 的方法将会被自动调用,用来处理 start_url 列表中的每一个 URL
def parse(self,response):
try:
data = response.body.decode()
selector = scrapy.Selector(text=data)
books = selector.xpath("//ul[@class='cf']")
#books = response.xpath("//ul[@class='cf']") 前面 3 行可用这行代替
books = books.xpath("./li[@data-rid]")
for book in books:
item = BookItem()
item["title"] = book.xpath("./a/text()").extract()
href = book.xpath("./a/@href").extract_first() # //read.qidian.com/chapter/qrqmtYSE7XFmzDX0o03xsg2/LOibR1_EzCTgn4SMoDUcDQ2
href = "http:"+href # 拼接url
yield scrapy.Request(url=href,callback=self.parse_detail,meta={
'item':item})
# 用scrapy.Request发起请求可以带上 meta={'item': item} 把之前已收集到的信息传递到新请求里
# 在新请求里用 item = response.meta('item') 接受过来,在 item 就可以继续添加新的收集的信息了
except Exception as err:
print(err)
items.py
定义了爬取结果的数据结构,爬取的数据会被赋值到成该 Item 对象
import scrapy
class BookItem(scrapy.Item):
title = scrapy.Field() # 存储标题
content = scrapy.Field() # 存储小说内容
pipelines.py
负责处理由蜘蛛从网页中抽取的项目,它的主要任务是清洗、验证、和存储数据
import os
class BookPipeline(object):
# 开启爬虫时执行,只执行一次
def open_spider(self,spider):
if os.path.exists("三体"):
pass
else:
os.mkdir("三体")
print("spider start")
# 处理提取的数据(保存数据)
def process_item(self, item, spider):
title = item['title']
content = item['content']
print(title)
with open("三体/"+title[0]+".txt","w") as f:
f.write('\t\t\t\t' + title[0] + '\n\n')
f.write(content)
return item
# 关闭爬虫时执行,只执行一次。 (如果爬虫中间发生异常导致崩溃,close_spider可能也不会执行)
def close_spider(self, spider):
print("spider end")
run.py
运行,开始爬取
from scrapy import cmdline
cmdline.execute("scrapy crawl mySpider -s LOG_ENABLED=False".split())
settings.py
定义了项目的全局配置
# 把下面的注释去掉
ITEM_PIPELINES = {
'book.pipelines.BookPipeline': 300,
}