创建项目:
scrapy startproject qiumeimei
建立爬虫应用:
scrapy genspider -t crawl meimei www.qiumeimei.com
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from qiumeimei.items import QiumeimeiItem
class MeimeiSpider(CrawlSpider):
name = 'meimei' #爬虫的名字跟重要
# allowed_domains = ['www.qiumeimei.com']
start_urls = ['http://www.qiumeimei.com/tag/gif'] #爬取的第一个url
rules = (
# 写入正则表达式,拿出页面里的能匹配到的所有a连接,在重新调用 parse_item方法
Rule(LinkExtractor(allow=r'http://www.qiumeimei.com/tag/gif/page/\d+'), callback='parse_item', follow=True),
)
def parse_item(self, response):
print("我到这儿了!!!")
# 截取路由,拿出page(页码) response.url = http://www.qiumeimei.com/tag/gif/page/2
img_page = response.url.split('/')[-1]
if img_page=='gif': #因为第一页的路由是 http://www.qiumeimei.com/tag/gif
img_page = "1"
div_list = response.xpath('//div[@class="home_main_wrap"]/div')
for div in div_list:
item = QiumeimeiItem()
# 图片名字
img_name = div.xpath('./div/h2/a/text()').extract_first()
if img_name:
item['img_name'] = img_name
# 图片的url (不要被页面的伪装所有迷惑,找到正确的url)
img_url = div.xpath('./div/p/img/@data-lazy-src').extract_first()
if img_url:
item['img_url'] = img_url
item['img_page'] = img_page
yield item
爬虫文件 meimei.py 源代码 结束。
import scrapy
class QiumeimeiItem(scrapy.Item):
# define the fields for your item here like:
# 定义存储的字段名称
img_name = scrapy.Field()
img_url = scrapy.Field()
img_page = scrapy.Field()
import scrapy
import os
from scrapy.utils.misc import md5sum
# 导入scrapy 框架里的 管道文件的里的图像 图像处理的专用管道文件
from scrapy.pipelines.images import ImagesPipeline
# 前提必须在settings.py 文件里定义一个文件的存放位置,然后引进来
from qiumeimei.settings import IMAGES_STORE as images_store
# 必须继承父类 ImagesPipeline
class QiumeimeiPipeline(ImagesPipeline):
# 重写父类的下载图片的方法
def get_media_requests(self, item, info):
# print(item['img_url'],item['img_page'],item['img_name'])
# 自动请求图片的url,转换为二进制下载
yield scrapy.Request(url=item['img_url'])
# 建立分级文件夹的方法
def item_completed(self, results, item, info):
page = item['img_page'] #第几页
img_name = item['img_name'] #图片的名称
print(f"当前正在下载第<<<{page}>>>页的图片")
# 新的图片存放位置
img_NEWpath = images_store + page + '/' #"./images/2/"
# 老的文件夹存放位置(也就是不定义文件夹的时候,自动存放的位置)
# 列表推导式 (详细介绍,会在以后的发表里~~~)
old_path_list = [x['path'] for t,x in results if t]
# 真正的图片存放位置
old_path = images_store + old_path_list[0] #"./images/full/meimei.gif" (自动创建的full文件夹)
# 建立文件夹
if not os.path.exists(img_NEWpath):
os.mkdir(img_NEWpath)
# 图片名字(图片的相对路径)
new_name = img_NEWpath + img_name + ".gif" #"./images/2/妹妹.gif"
# 替换图片的名字,(也就是替换存放图片的位置)
# print("图片老名字是%s------图片新名字是%s"%(old_path,new_name))
os.rename(old_path,new_name)
return item
# 重写下载规则(有点深奥,本人暂时没看懂,哪位大神看懂了,还请评论下方留言,指点一二,我当感激不尽!!!)
def image_downloaded(self, response, request, info):
checksum = None
for path, image, buf in self.get_images(response, request, info):
if checksum is None:
buf.seek(0)
checksum = md5sum(buf)
width, height = image.size
if self.check_gif(image):
self.persist_gif(path, response.body, info)
else:
self.store.persist_file(
path, buf, info,
meta={'width': width, 'height': height},
headers={'Content-Type': 'image/jpeg'})
return checksum
def check_gif(self, image):
if image.format is None:
return True
def persist_gif(self, key, data, info):
root, ext = os.path.splitext(key)
absolute_path = self.store._get_filesystem_path(key)
self.store._mkdir(os.path.dirname(absolute_path), info)
f = open(absolute_path, 'wb') # use 'b' to write binary data.
f.write(data)
管道文件源代码 结束!!!
定义图片的存放位置(随意位置):
IMAGES_STORE = './images/'
伪装浏览器:
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
修改是否遵守 robots协议
ROBOTSTXT_OBEY = False
去除不重要的日志信息,加上底下两句话(随意位置):
LOG_LEVEL = 'ERROR' #只看见报错的信息
LOG_FILE = 'log.txt' #可以自动的创建一个log.txt文件,把报错的信息存入里面。
千万不要忘了打开管道文件的设置 (开关)!!!
ITEM_PIPELINES = {
'qiumeimei.pipelines.QiumeimeiPipeline': 300,
}
好了,,settings.py 文件 源代码 结束
最后运行文件:
scrapy crawl meimei --nolog
from scrapy import cmdline
# ()里存储执行的命令行 ,因为是字符串,所有截取一下空格,cmd才认识
cmdline.execute("scrapy crawl meimei --nolog".split())
对了,,还有图片呢:
算了,,,有点不方便,,,嘿嘿,,自己下载慢慢看吧!!!