利用Scrapy爬虫框架快速进行数据抓取
欢迎大家去博客冰山一树Sankey,浏览效果更好。直接右上角搜索该标题即可

博客园主页:博客园主页-冰山一树Sankey
CSDN主页:CSDN主页-冰山一树Sankey
你逆光而来,配得上世间所有的美好。
一. 基础概述
Scrapy的基础概述与安装,有大佬已经写的很详细了,具体可去看看大佬的文章,下面是文章链接
Scrapy爬虫框架,入门案例(非常详细)_ck784101777的博客-CSDN博客_scrapy
我这里就加一些文章里没有的东西吧→_→ ←_←
二. 存储到MySQL
在管道pipelines.py文件中添加一个新的类
#添加一个Mysql管道
class MysqlPipeline(object):
#数据库初始化
def open_spider(self,spider):
#连接到mysql数据库
self.db=pymysql.connect(
host=MYSQL_HOST,
user=MYSQL_USER,
password=MYSQL_PWD,
database=MYSQL_DB,
charset=MYSQL_CHAR
)
#创建游标操作数据库
self.cursor=self.db.cursor()
#数据库的操作
def process_item(self, item, spider):
ins='insert into films value(%s,%s,%s)'
#插入时间,演员,上映时间
L=[item['name'],item['star'],item['time']]
self.cursor.execute(ins,L)
#提交数据库
self.db.commit()
return item
#关闭数据库
def close_spidr(self,spider):
#关闭游标
self.cursor.close()
#关闭数据库
self.db.close()
在settings.py中定义数据库信息,默认已经建好了数据库
#添加数据库配置信息
MYSQL_HOST='localhost'
MYSQL_USER='root'
MYSQL_PWD='123456'
MYSQL_DB='filmsdb'
MYSQL_CHAR='utf8'
将ITEM_PIPELINES取消注释,并添加Mysql管道配置
ITEM_PIPELINES = {
'Maoyan_thread.pipelines.MaoyanThreadPipeline': 300,# 400表示权重
#添加Mysql管道配置
'Maoyan_thread.pipelines.MysqlPipeline': 500,# 权重值越小,越优先执行!
}
PIPELINES管道配置的一些注意事项
- 使用之前需要在settings中开启
- pipeline在setting中键表示位置(即pipeline在项目中的位置可以自定义),值表示距离引擎的远近,越近数据会越先经过:权重值小的优先执行
- 有多个pipeline的时候,process_item的方法必须return item,否则后一个pipeline取到的数据为None值
- pipeline中process_item的方法必须有,否则item没有办法接受和处理
- process_item方法接受item和spider,其中spider表示当前传递item过来的spider
- open_spider(spider) :能够在爬虫开启的时候执行一次
- close_spider(spider) :能够在爬虫关闭的时候执行一次
- 上述俩个方法经常用于爬虫和数据库的交互,在爬虫开启的时候建立和数据库的连接,在爬虫关闭
的时候断开和数据库的连接
三. 非结构化的数据存储
使用scrapy框架我们除了要下载文本,还有可能需要下载图片,scrapy提供了ImagePipeline来进行图片的下载。
这里以爬取360图片/美女为例来进行说明,话不多说,直接开始
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GqqespVL-1646291370487)(https://gitee.com/Omnivore_zhang/cloud-image/raw/master/Spider/image-20220302195243757.png)]
先创建个scrapy项目,我命名为So,这里创建项目默认已经会了,不会的去看基础概述一
然后找到spiders文件夹下的so.py,再SoSpider类中添加下面代码
name = 'so'
allowed_domains = ['image.so.com']
#注释start_urls
# start_urls = ['http://image.so.com/']
url='https://image.so.com/zjl?ch=beauty&sn={}'
#多线程,重写start_requests方法
def start_requests(self):
#爬取4页的数据
for sn in range(0,100,30):
url=self.url.format(sn)
yield scrapy.Request(
url=url,
callback=self.parse_page
)
def parse_page(self, response):
# 将json转换为字典
html=json.loads(response.text)
print(html)
#创建item对象
item=SoItem()
for img in html['list']:
item['img_link']=img['qhimg_url']
item['img_title']=img['title']
yield item #甩给了管道文件
在管道中添加一个类,添加以下方法
#导入ImagesPipeline
from scrapy.pipelines.images import ImagesPipeline
#继承管道类ImagesPipeline类
class SoPipeline(ImagesPipeline):
def get_media_requests(self, item, info):
print(item)
yield scrapy.Request(
url=item['img_link'],
meta= {'title':item['img_title']}
)
def file_path(self, request, response=None, info=None, *, item=None):
title=request.meta['title']
filename = title + "." + request.url.split('.')[-1]
return filename
items.py文件中添加数据定义
class SoItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
img_link=scrapy.Field()
img_title=scrapy.Field()
settings.py中配置
#配置日志权限
LOG_LEVEL='WARNING'
#配置相片路径
IMAGES_STORE='images/'
#关闭机器人协议
ROBOTSTXT_OBEY = False
大概就可以了,重点就是继承ImagesPipeline类
四. scrapy shell的使用
使用scrapy shell可以测试网址的url,headers,还能通过先通过xpath获取网页元素再写到代码中,减少调试次数
基本使用
http://httpbin.org/get
# scrapy shell URL地址 直接在cmd中写
scrapy shell http://www.baidu.com
*1、request.url : 请求URL地址
*2、request.headers :请求头(字典)
*3、reqeust.meta :item数据传递,定义代理(字典)
4、response.text :字符串
5、response.body :bytes
6、response.xpath('/html/head/title/text()').get()#更真实
exit();#退出
五. 设置随机User-Agent
通过改变User-Agent,可降低被爬取网址检测到的风险。
5.1 少量的User-Agent
方法一:
在settings.py中设置
#取消注释,添加User-Agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 Edg/98.0.1108.62'
或者设置在
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 Edg/98.0.1108.62'
}
方法二:
在spider文件中的yield里面进行设置
# spider
yield scrapy.Request(url,callback=函数名,headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 Edg/98.0.1108.62'
})
5.2 大量的User-Agent
middlewares.py设置中间件
1、获取User-Agent
# 方法1 :新建useragents.py,存放大量User-Agent,random模块随机切换
# 方法2 :安装fake_useragent模块(sudo pip3 install fack_useragent)
from fake_useragent import UserAgent
ua_obj = UserAgent()
ua = ua_obj.random
2、middlewares.py新建中间件类
class RandomUseragentMiddleware(object):
def process_request(self,reuqest,spider):
ua = UserAgent()
request.headers['User-Agent'] = ua.random
3、settings.py添加此下载器中间件
DOWNLOADER_MIDDLEWARES = {
# 'Douban.middlewares.DoubanDownloaderMiddleware': 543,
'Douban.middlewares.RandomUseragentMiddleware':300
}
六. 设置随机代理
1、新建一个proxies.py,定义一个列表,用于存储所有的代理IP
proxies_list=[xxxx,xxxx,xxxx,xxxx,xxxx]
2、middlewares.py新建中间件类
class RandomProxyDownloaderMiddleware(object):
def process_request(self,request,spider):
request.meta['proxy'] = proxies_list.chioce()
def process_exception(self,request,exception,spider):
return request
3、settings.py添加此下载器中间件
DOWNLOADER_MIDDLEWARES = {
# 'Douban.middlewares.DoubanDownloaderMiddleware': 543,
'Douban.middlewares.RandomProxyDownloaderMiddleware':300
}
七. 设置cookies
有的网址需要设置cookies才能进行访问
方法一
直接在settings中设置
#取消这里的注释,让后添加cookies
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'Cookie': 'OUTFOX_SEARCH_USER_ID=-2094518326@10.110.96.159; OUTFOX_SEARCH_USER_ID_NCOO=654528686.5393351; JSESSIONID=aaabc05LV06Lq7Stpyd9x; ___rl__test__cookies=1646102934467',
}
然后再取消Disable cookies的注释,注意其值必须是False才行
# Disable cookies (enabled by default)
COOKIES_ENABLED = False
方法二
在spiders下面中的解析文件设置
#添加方法,返回为字典类型
def get_cookie(self):
cs='OUTFOX_SEARCH_USER_ID=-2094518326@10.110.96.159; OUTFOX_SEARCH_USER_ID_NCOO=654528686.5393351; JSESSIONID=aaabc05LV06Lq7Stpyd9x; ___rl__test__cookies=1646102934467'
cs_list=cs.split(';')
cs_dict={}
for c in cs_list:
cs_dict[c.split('=')[0]]=c.split('=')[1]
return cs_dict
然后yield里面直接赋值
yield scrapy.FormRequest(
url=post_url,
formdata=data,
callback=self.parse,
cookies=self.get_cookie()
)
方法三
在middlewares.py中添加类
class YoudaoCOookie(object):
def get_cookie(self):
cs = 'OUTFOX_SEARCH_USER_ID=-2094518326@10.110.96.159; OUTFOX_SEARCH_USER_ID_NCOO=654528686.5393351; JSESSIONID=aaabc05LV06Lq7Stpyd9x; ___rl__test__cookies=1646102934467'
cs_list = cs.split(';')
cs_dict = {}
for c in cs_list:
cs_dict[c.split('=')[0]] = c.split('=')[1]
return cs_dict
def process_request(self,request,spider):
request.cookies=self.get_cookie()
然后在settings中设置
DOWNLOADER_MIDDLEWARES = {
# 'Youdao.middlewares.YoudaoDownloaderMiddleware': 543,
'Youdao.middlewares.YoudaoCOookie':500
}