我们都知道我们平常想下载一些漂亮的图片来装饰自己的桌面,可是找到了都是需要收费的网站,真的很恼火,所以今天小编,可能要带大家实现这么一个工具,可以用来爬取某个网站的好看的图片
兴不兴奋啊,是的超级兴奋,现在这里透漏一下,以后每天都会同时更新《今日金融词汇》《每日一道 python 面试题》,敬请期待,谢谢关注,欢迎点赞,关注,收藏三连击,只看,不关注,不是好汉,哈哈开玩笑
哈哈,行了我们进入主题吧
附上链接地址
https://image.so.com/
创建项目前,我们需要来分析下网站数据,进入 首页,点击美女,我们可以知道跳转到这个页面,可以看出数据是通过 jsonp 的形式,进行 ajax 渲染的,而且每一次刷新页面这个函数都会随机变化,也就是说可能写出来的代码是具有时效性的
我们再随机点击一张图片进入看更加详细的页面,
就来到了这个页面,我们 f12 一下,可以看到数据是这样的,具有每张图片的详细信息,点击这个链接,进入 preview
https://image.so.com/zjl?ch=beauty&direction=next&sn=0&pn=30&prevsn=-1
我们可以看到有图片的详细信息了,id,title,imgurl
然后我们再看看 header,里面需要哪些参数,从图上看,我们需要 ch, sn, pn
我们可以拼接出来这样一个链接,读者可以自行访问
https://image.so.com/zjl?ch=beauty&direction=next&prevsn=-1&sn=180
创建项目
scrapy startproject images
定义我们的 Item.py
我们通常爬取图片需要爬取保存图片的链接,图片,图片的名称,所以我们定义了这么一个 Item.py 类名
-
# -*- coding: utf
-8 -*-
-
-
# Define here the models
for your scraped items
-
#
-
# See documentation in:
-
# https:
//docs.scrapy.org/en/latest/topics/items.html
-
-
import scrapy
-
-
-
class ImagesItem(scrapy.Item):
-
# define the fields
for your item here like:
-
# name = scrapy.Field()
-
collection = table =
'images'
-
imageid = scrapy.Field()
-
group_title = scrapy.Field()
-
url = scrapy.Field()
spider 蜘蛛
根据我们上面的分析,我们需要一些固定参数,ch,关键字,direction,prevsn,这几个固有参数,当然,我们也可以通过把 ch 动态输入的方式来爬取你需要的图片,这里就只是设置死了,sn 表示起始页数,这个是动态变化的
-
# -*- coding: utf
-8 -*-
-
import json
-
from urllib.parse
import urlencode
-
from images.items
import ImagesItem
-
from scrapy
import Spider, Request
-
-
-
class ImagesSpider(Spider):
-
name =
'images'
-
allowed_domains = [
'image.so.com']
-
-
def start_requests(self):
-
# 表单数据
-
data = {
-
'ch':
'beauty',
-
'direction':
'next',
-
'prevsn':
-1,
-
}
-
# 爬虫起始地址
-
base_url =
'http://image.so.com/zjl?'
-
# page列表从
1到
50页循环递归,其中MAX_PAGE为最大页数
-
for page in
range(
1, self.settings.get(
'MAX_PAGE') +
1):
-
data[
'sn'] = page*
30
-
params = urlencode(data)
-
# spider实际爬取的地址是api接口,如http:
//image.so.com/zj?ch=wallpaper&sn=30&listtype=new&temp=1
-
url = base_url + params
-
yield Request(url, self.parse)
-
-
def parse(self, response):
-
# 因response返回的数据为json格式,故json.loads解析
-
result = json.loads(response.text)
-
res = result.get(
'list')
-
if res:
-
for image in res:
-
item = ImagesItem()
-
item[
'imageid'] = image.get(
'id') # 图片id
-
item[
'title'] = image.get(
'title') # 图片标题
-
item[
'url'] = image.get(
'qhimg_url') # 图片地址
-
yield item
因为这个网站具有反扒功能,所以我们需要准备一些 user_agents,由于 user_agents太多了,不太方便展示,所以我就剪切了三个展示在这里,需要的话,可以关注公众号,回复‘进群’,加我微信,私信发你
-
agents = [
-
"Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1;AcooBrowser;.NETCLR1.1.4322;.NETCLR2.0.50727)",
-
"Mozilla/4.0(compatible;MSIE7.0;WindowsNT6.0;AcooBrowser;SLCC1;.NETCLR2.0.50727;MediaCenterPC5.0;.NETCLR3.0.04506)",
-
"Mozilla/4.0(compatible;MSIE7.0;AOL9.5;AOLBuild4337.35;WindowsNT5.1;.NETCLR1.1.4322;.NETCLR2.0.50727)",
-
]
我们在写中间件的时候,需要用到上面的 user_agents.py 文件
定义中间件
我们需要随机性的选择一个 user_agents ,这样就可以做到让对方不知道我们是同一台电脑在访问页面了,做到可以不被禁掉,我们可以定义一个随机类,
-
import random
-
from images.user_agents
import agents
-
-
class RandomUserAgentMiddelware(object):
-
""
"
-
换User-Agent
-
"
""
-
def process_request(self, request, spider):
-
request.headers[
'User-Agent'] = random.choice(agents)
接下里就是定义管道了
其实管道的意义就是充当数据库保存的作用,根据我的理解,在这里我们需要过滤信息,创建数据库,连接数据库,将数据插入到数据库中
我们这里需要用到我们之前讲过的 pymongo 这个库
-
import pymongo
-
from scrapy
import Request
-
from scrapy.exceptions
import DropItem
-
from scrapy.pipelines.images
import ImagesPipeline
-
-
# 数据信息存储至 mongo 中
-
class MongoPipeline(object):
-
def __init__(self,mongo_uri, mongo_port, mongo_db):
-
self.mongo_uri = mongo_uri
-
self.mongo_port = mongo_port
-
self.mongo_db = mongo_db
-
-
@classmethod
-
def from_crawler(cls, crawler):
-
return cls(
-
mongo_uri=crawler.settings.get(
'MONGO_URI'),
-
mongo_port=crawler.settings.get(
'MONGO_PORT'),
-
mongo_db=crawler.settings.get(
'MONGO_DB'),
-
)
-
# 链接数据库
-
def open_spider(self, spider):
-
self.client = pymongo.MongoClient(host=self.mongo_uri, port=self.mongo_port)
-
self.db = self.client[self.mongo_db]
-
# 插入数据
-
def process_item(self, item, spider):
-
self.db[item.collection].insert(dict(item))
-
return item
-
# 关闭数据库
-
def close_spider(self, spider):
-
self.client.
close()
-
# 下载图片
-
class ImagePipeline(ImagesPipeline):
-
def file_path(self, request, response=None, info=None):
-
url = request.url
-
file_name = url.split(
'/')[
-1]
-
return file_name
-
-
def item_completed(self, results, item, info):
-
image_paths = [x[
'path']
for ok, x in results
if ok]
-
if not image_paths:
-
raise DropItem(
'Image Downloaded Failed')
-
return item
-
-
def get_media_requests(self, item, info):
-
yield Request(item[
'url'])
scrapy.setting 设置
-
# -*- coding: utf
-8 -*-
-
-
# Scrapy settings
for images project
-
-
BOT_NAME =
'images' # 其实就是爬虫的名字
-
-
SPIDER_MODULES = [
'images.spiders'] # 爬虫模块
-
NEWSPIDER_MODULE =
'images.spiders' # 爬虫的命名空间
-
-
-
# Crawl responsibly by identifying yourself (and your website) on the user-agent
-
USER_AGENT =
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36' # 本机浏览器的 user_agent
-
-
# Obey robots.txt rules
-
ROBOTSTXT_OBEY = True # 遵循爬虫规则
-
-
# 抓取最大页数
-
MAX_PAGE =
50 # 设置爬取最大页码
-
# MONGO信息设置
-
MONGO_URI =
'localhost' # 本地数据库 uri
-
MONGO_PORT =
27017 # 数据库端口
-
MONGO_DB =
'images' # 数据库名字
-
-
# 图片下载路径
-
IMAGES_STORE =
'./image1' # 图片存储路径
-
-
# Obey robots.txt rules
-
ROBOTSTXT_OBEY = False
-
-
DOWNLOAD_DELAY =
2 # 延迟
-
# The download delay setting will honor only one of:
-
-
# See https:
//doc.scrapy.org/en/latest/topics/downloader-middleware.html
-
DOWNLOADER_MIDDLEWARES = { # 刚刚我们编写的随机 agent 中间件就在这里引用说明了,数字为权限级别
-
'images.middlewares.RandomUserAgentMiddelware':
543,
-
}
-
-
ITEM_PIPELINES = { # 管道权限声明
-
'images.pipelines.ImagePipeline':
300,
-
'images.pipelines.MongoPipeline':
301,
-
}
到此为止,我们的爬虫实际上已经完成了,所谓欲成大事,只欠东风来助一臂之力了,就是运行代码了
scrapy crawl images
当当当,好多美女啊
转载:https://blog.csdn.net/qq_36772866/article/details/105803786