项目5 爬取图书网站数据
spiders/SpiderBook.py
import scrapy
from scrapy.selector import Selector
from SpiderBook.items import BookItem
import os
class MySpider(scrapy.Spider):
name = "mySpider"
def start_requests(self):
#初始化图像文件夹,删除原有的图像
try:
if not os.path.exists("download"):
os.mkdir("download")
images = os.listdir("download")
for img in images:
s = os.path.join("download",img)
os.remove(s)
except Exception as err:
print(err)
#url ='http://127.0.0.1:5000'
url="http://www.rj-jwb.com.cn/spiderbook/chapter5/"
self.ID=0
yield scrapy.Request(url=url,callback=self.parse)
def getFileExt(self, url):
p = url.rindex(".")
if p >= 0:
s = url[p:]
if s[len(s) - 1] == "/":
s = s[0:len(s) - 1]
else:
s = ""
return s
def parse(self, response):
selector=Selector(text=response.body.decode())
lis=selector.xpath("//ul/li")
for li in lis:
self.ID+=1
ID="%06d"%self.ID
div=li.xpath(".//div[@class='info']")
d=div.xpath(".//div[@class='title']")
bTitle=d.xpath("./h3/text()").extract_first()
d=div.xpath(".//div[@class='author']")
bAuthor=d.xpath("./span[@class='attrs']/text()").extract_first()
d=div.xpath(".//div[@class='publisher']")
bPublisher=d.xpath("./span[@class='attrs']/text()").extract_first()
d=div.xpath(".//div[@class='date']")
bDate=d.xpath("./span[@class='attrs']/text()").extract_first()
d=div.xpath(".//div[@class='price']")
bPrice=d.xpath("./span[@class='attrs']/text()").extract_first()
bDetail=div.xpath(".//div[@class='detail']/text()").extract_first()
src=li.xpath(".//div[@class='pic']//img/@src").extract_first()
if src:
src=response.urljoin(src).strip("/")
bImage=ID+self.getFileExt(src)
request=scrapy.Request(url=src,callback=self.download)
request.meta["bImage"]=bImage
yield request
else:
bImage=""
#创建BookItem对象
item=BookItem()
item["ID"]=ID
item["bTitle"]=bTitle.strip() if bTitle else ""
item["bAuthor"]=bAuthor.strip() if bAuthor else ""
item["bPublisher"]=bPublisher.strip() if bPublisher else ""
item["bDate"]=bDate.strip() if bDate else ""
item["bPrice"]=bPrice.strip() if bPrice else ""
item["bDetail"]=bDetail.strip() if bDetail else ""
item["bImage"]=bImage
yield item
href=selector.xpath("//div[@class='paging']//a[position()=last()-1]/@href").extract_first().strip()
if href!="#":
href=response.urljoin(href)
yield scrapy.Request(url=href,callback=self.parse)
def download(self,response):
bImage = response.meta["bImage"]
#print("downloading",bImage)
f=open("download\\"+bImage,"wb")
f.write(response.body)
f.close()
print("downloaded",bImage)
items.py
# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class BookItem(scrapy.Item):
# define the fields for your item here like:
ID=scrapy.Field()
bTitle = scrapy.Field()
bAuthor = scrapy.Field()
bPublisher = scrapy.Field()
bDate = scrapy.Field()
bPrice = scrapy.Field()
bDetail = scrapy.Field()
bImage = scrapy.Field()
pipeline.py
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
import sqlite3
import os
class BookPipeline(object):
def open_spider(self,spider):
print("open_spider")
self.con=sqlite3.connect("books.db")
self.cursor=self.con.cursor()
try:
self.cursor.execute("drop table books")
except:
pass
sql="create table books (ID varchar(8) primary key,bTitle varchar(256),bAuthor varchar(256),bPublisher varchar(256),bDate varchar(256),bPrice varchar(256),bDetail text,bImage varchar(256))"
self.cursor.execute(sql)
self.count=0
if not os.path.exists("download"):
os.mkdir("download")
def close_spider(self,spider):
print("close_spider")
print("Total ",self.count)
#self.showDB()
self.con.commit()
self.con.close()
def insertDB(self,ID,bTitle,bAuthor,bPublisher,bDate,bPrice,bDetail,bImage):
try:
sql="insert into books (ID,bTitle,bAuthor,bPublisher,bDate,bPrice,bDetail,bImage) values (?,?,?,?,?,?,?,?)"
self.cursor.execute(sql,[ID,bTitle,bAuthor,bPublisher,bDate,bPrice,bDetail,bImage])
except Exception as err:
print(err)
def showDB(self):
self.cursor.execute("select ID,bTitle,bAuthor,bPublisher,bDate,bPrice,bDetail,bImage from books")
rows=self.cursor.fetchall()
for row in rows:
for r in row:
print(r)
def process_item(self, item, spider):
self.count += 1
ID=item["ID"]
bTitle=item["bTitle"]
bAuthor=item["bAuthor"]
bPublisher=item["bPublisher"]
bDate=item["bDate"]
bPrice=item["bPrice"]
bDetail=item["bDetail"]
bImage=item["bImage"]
print(ID,bTitle)
self.insertDB(ID,bTitle,bAuthor,bPublisher,bDate,bPrice,bDetail,bImage)
return item
settings.py
# -*- coding: utf-8 -*-
# Scrapy settings for SpiderBook project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# https://doc.scrapy.org/en/latest/topics/settings.html
# https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
# https://doc.scrapy.org/en/latest/topics/spider-middleware.html
BOT_NAME = 'SpiderBook'
SPIDER_MODULES = ['SpiderBook.spiders']
NEWSPIDER_MODULE = 'SpiderBook.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'SpiderBook (+http://www.yourdomain.com)'
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32
# Configure a delay for requests for the same website (default: 0)
# See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
#DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16
# Disable cookies (enabled by default)
#COOKIES_ENABLED = False
# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False
# Override the default request headers:
#DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
#}
# Enable or disable spider middlewares
# See https://doc.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
# 'SpiderBook.middlewares.SpiderbookSpiderMiddleware': 543,
#}
# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
# 'SpiderBook.middlewares.SpiderbookDownloaderMiddleware': 543,
#}
# Enable or disable extensions
# See https://doc.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#}
# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'SpiderBook.pipelines.BookPipeline': 300,
}
# Enable and configure the AutoThrottle extension (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False
# Enable and configure HTTP caching (disabled by default)
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
show.py
import sqlite3
try:
con=sqlite3.connect("books.db")
cursor=con.cursor()
cursor.execute("select ID,bTitle from books")
rows=cursor.fetchall()
for row in rows:
print(row[0]," ",row[1])
print("Total ",len(rows))
con.close()
except Exception as err:
print(err)
runSpider.py
from scrapy import cmdline
cmdline.execute("scrapy crawl mySpider -s LOG_ENABLED=False".split())