赞
踩
Scrapy
作为一个优秀的Python
爬虫框架,深受博主喜爱,尽管博主从事大部分工作是前端开发,但也会对爬虫,数据库以及后台的工作感兴趣。
最近又有了新的任务,能够以相同的数据库表结构去存储爬取的数据;在以往,博主虽然说会爬虫,但也只是非常浅显的,一个Scrapy
项目只能跑一个爬虫,而实际上是可以在一个Scrapy
项目中写多个爬虫的。
创建一个新的Scrapy
项目,在工作间文件夹打开控制台,输入以下命令:
scrapy startproject xxx(xxx为项目名)
像上图,当你电脑已经成功安装scrapy之后,只需这一句命令就可以创建一个全新的scrapy项目了
目录结构如下:
这里博主修改了一下目录结构,因总共要爬取三个不同的网站,在spiders文件夹下添加了site01_spider.py
,site02_spider.py
,site03_spider.py
三个爬虫文件,在demo目录下添加db.py
数据库存储文件,在最外层大目录下添加demo_main.py
启动爬虫文件,如下图:
db.py
(新增):配置相关的SQL初始化创建表方法,数据库插件mysql
使用pymysql
插件,mssql
则使用pymssql
插件。
import pymssql
class demoInfo(object):
def __init__(self, tableName):
self.tableName = tableName
def add(self, xxx):
# 这里做连接数据库,插入数据库操作
db = pymssql.connect(
host="xxx",
user="xxx",
password="xxx",
database="xxx"
)
cursor = db.cursor()
sql = "select * from 'xxxx'"
cursor.execute(sql)
db.commit()
cursor.close()
db.close()
def create(self, xxx):
# 这里做初始化创建表操作 SQL语句有变 基本同上
print('create')
items.py
:配置需要爬取的字段。
class DemoItem(scrapy.Item):
# define the fields for your item here like:
name = scrapy.Field()
pass
middlewares.py
:可编写用于随机选取USER_AGENTS
的类方法,按需也可在下载中间件process_response
回调里使用selenium
做请求回调前的控制浏览器行为的操作(这里不做展开)。
pipelines.py
:可根据爬虫名称来区分要插入的数据库。
from source.db import dbInfo
class DemoPipeline(object):
def process_item(self, item, spider):
dbName = ''
# 根据蜘蛛名来判断数据库的表名
if spider.name == 'site01_spider':
dbName = 'site01'
elif spider.name == 'site02_spider':
dbName = 'site02'
else:
dbName = 'site03'
source = dbInfo(dbName)
source.create(dbName)
source.add(item["name"])
return item
settings.py
:项目配置文件,按需配置(这里也不做展开)。
source_main.py
(新增):该文件作为爬虫启动的入口文件,可由用户输入决定所要启动的爬虫。
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from demo.spiders.site01_spider import site01Spider
from demo.spiders.site02_spider import site02Spider
from demo.spiders.site03_spider import site03Spider
from demo.db import dbInfo
# 在Scrapy框架内控制爬虫
if __name__ == "__main__":
process = CrawlerProcess(get_project_settings())
# 控制台主界面
main = int(input("请输入爬取网站:(1为site01 2为site02 3为site03)"))
if main == 1:
process.crawl("site01_spider")
elif main == 2:
process.crawl("site02_spider")
elif main == 3:
process.crawl("site03_spider")
else:
print("输入错误!")
pass
print('-----爬虫启动-----')
process.start()
site01到site03爬虫文件,这里举其中一个文件为例展开:
博主使用到了selenium
,故需要Chrome
的webdriver
支持,同时还需要相关的配置
import scrapy
from demo.items import DemoItem
from selenium import webdriver
from selenium.webdriver.chrome.options import Options # 使用无头浏览器
# 无头浏览器设置
chorme_options = Options()
chorme_options.add_argument("--headless")
chorme_options.add_argument("--disable-gpu")
class site01Spider(scrapy.Spider):
name = 'site01_spider'
allowed_domains = [
'www.site01xx.com',
'www.site01yy.com',
'www.site01zz.com'
]
start_urls = [
'https://www.site01xx.com/list/index.html'
]
def __init__(self):
self.page = 1 # 当前页码
self.url_index = 0 # 当前url_list的下标值
# url_list可配置相同的网页结构,不同的站点的url,可支持不同的域名
# 如果为不同域名,需要在allowed_domains添加对应的允许域名
self.url_list = [
'https://www.site01xx.com/list/index.html',
'https://www.site01yy.com/list/index.html',
'https://www.site01zz.com/list/index.html'
]
self.browser = webdriver.Chrome(chrome_options=chorme_options)
super().__init__()
# 整个爬虫结束后关闭浏览器
def close(self, spider):
print('退出爬虫')
self.browser.quit()
def parse(self, response):
# 每进入一次回调,page就自加1(页码)
self.page = self.page + 1
# 回调中对数据进行清洗,以及判断是否需要进行切页,进入详情页的操作
item = DemoItem()
name = 'xxx'
# 操作的最后,将数据压入字段后,传输给管道
item['name'] = name
yield item
# 假设总页码为100,爬完100页后进入下一个站点
if self.page <= 100:
yield scrapy.Request(url=self.url_list[self.url_index] + "?page=" + str(self.page), callback=self.parse)
else:
# 进入这里,证明已经爬完了某一个站点
print('-----进入下一个站点-----')
self.page = 1 # 页码重置为1
self.url_index = self.url_index + 1 # 数组下标自增1
yield scrapy.Request(url=self.url_list[self.url_index], callback=self.parse)
到这基本上就完成demo的编写,仅需按照自身需求替换相对应的示例代码即可完成。
尽管爬虫并非博主的编程方向,但是博主还是非常乐意去钻研学习,多学习一些别的技术,对自身的提升还是非常有帮助的!
博主作为Python
菜鸟级选手,文章有哪里写得不对的地方还请慷慨指出;同样的,有什么不懂的小伙伴也可以留言,博主当会尽力解答,大家一起共同进步!
参考网站:Scrapy官方文档
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。