飞道的博客

Scrapy(4)spider 帮助你寻找最美小姐姐

499人阅读  评论(0)

我们都知道我们平常想下载一些漂亮的图片来装饰自己的桌面,可是找到了都是需要收费的网站,真的很恼火,所以今天小编,可能要带大家实现这么一个工具,可以用来爬取某个网站的好看的图片

兴不兴奋啊,是的超级兴奋,现在这里透漏一下,以后每天都会同时更新《今日金融词汇》《每日一道 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 类名


   
  1. # -*- coding: utf -8 -*-
  2. # Define here the models for your scraped items
  3. #
  4. # See documentation in:
  5. # https: //docs.scrapy.org/en/latest/topics/items.html
  6. import scrapy
  7. class ImagesItem(scrapy.Item):
  8. # define the fields for your item here like:
  9. # name = scrapy.Field()
  10. collection = table = 'images'
  11. imageid = scrapy.Field()
  12. group_title = scrapy.Field()
  13. url = scrapy.Field()

spider 蜘蛛

根据我们上面的分析,我们需要一些固定参数,ch,关键字,direction,prevsn,这几个固有参数,当然,我们也可以通过把 ch 动态输入的方式来爬取你需要的图片,这里就只是设置死了,sn 表示起始页数,这个是动态变化的


   
  1. # -*- coding: utf -8 -*-
  2. import json
  3. from urllib.parse import urlencode
  4. from images.items import ImagesItem
  5. from scrapy import Spider, Request
  6. class ImagesSpider(Spider):
  7. name = 'images'
  8. allowed_domains = [ 'image.so.com']
  9. def start_requests(self):
  10. # 表单数据
  11. data = {
  12. 'ch': 'beauty',
  13. 'direction': 'next',
  14. 'prevsn': -1,
  15. }
  16. # 爬虫起始地址
  17. base_url = 'http://image.so.com/zjl?'
  18. # page列表从 150页循环递归,其中MAX_PAGE为最大页数
  19. for page in range( 1, self.settings.get( 'MAX_PAGE') + 1):
  20. data[ 'sn'] = page* 30
  21. params = urlencode(data)
  22. # spider实际爬取的地址是api接口,如http: //image.so.com/zj?ch=wallpaper&sn=30&listtype=new&temp=1
  23. url = base_url + params
  24. yield Request(url, self.parse)
  25. def parse(self, response):
  26. # 因response返回的数据为json格式,故json.loads解析
  27. result = json.loads(response.text)
  28. res = result.get( 'list')
  29. if res:
  30. for image in res:
  31. item = ImagesItem()
  32. item[ 'imageid'] = image.get( 'id') # 图片id
  33. item[ 'title'] = image.get( 'title') # 图片标题
  34. item[ 'url'] = image.get( 'qhimg_url') # 图片地址
  35. yield item

因为这个网站具有反扒功能,所以我们需要准备一些 user_agents,由于 user_agents太多了,不太方便展示,所以我就剪切了三个展示在这里,需要的话,可以关注公众号,回复‘进群’,加我微信,私信发你


   
  1. agents = [
  2. "Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1;AcooBrowser;.NETCLR1.1.4322;.NETCLR2.0.50727)",
  3. "Mozilla/4.0(compatible;MSIE7.0;WindowsNT6.0;AcooBrowser;SLCC1;.NETCLR2.0.50727;MediaCenterPC5.0;.NETCLR3.0.04506)",
  4. "Mozilla/4.0(compatible;MSIE7.0;AOL9.5;AOLBuild4337.35;WindowsNT5.1;.NETCLR1.1.4322;.NETCLR2.0.50727)",
  5. ]

我们在写中间件的时候,需要用到上面的 user_agents.py 文件

定义中间件

我们需要随机性的选择一个 user_agents ,这样就可以做到让对方不知道我们是同一台电脑在访问页面了,做到可以不被禁掉,我们可以定义一个随机类,


   
  1. import random
  2. from images.user_agents import agents
  3. class RandomUserAgentMiddelware(object):
  4. "" "
  5. 换User-Agent
  6. " ""
  7. def process_request(self, request, spider):
  8. request.headers[ 'User-Agent'] = random.choice(agents)

接下里就是定义管道了

其实管道的意义就是充当数据库保存的作用,根据我的理解,在这里我们需要过滤信息,创建数据库,连接数据库,将数据插入到数据库中

我们这里需要用到我们之前讲过的 pymongo 这个库


   
  1. import pymongo
  2. from scrapy import Request
  3. from scrapy.exceptions import DropItem
  4. from scrapy.pipelines.images import ImagesPipeline
  5. # 数据信息存储至 mongo 中
  6. class MongoPipeline(object):
  7. def __init__(self,mongo_uri, mongo_port, mongo_db):
  8. self.mongo_uri = mongo_uri
  9. self.mongo_port = mongo_port
  10. self.mongo_db = mongo_db
  11. @classmethod
  12. def from_crawler(cls, crawler):
  13. return cls(
  14. mongo_uri=crawler.settings.get( 'MONGO_URI'),
  15. mongo_port=crawler.settings.get( 'MONGO_PORT'),
  16. mongo_db=crawler.settings.get( 'MONGO_DB'),
  17. )
  18.    # 链接数据库
  19. def open_spider(self, spider):
  20. self.client = pymongo.MongoClient(host=self.mongo_uri, port=self.mongo_port)
  21. self.db = self.client[self.mongo_db]
  22.    # 插入数据
  23. def process_item(self, item, spider):
  24. self.db[item.collection].insert(dict(item))
  25. return item
  26. # 关闭数据库
  27. def close_spider(self, spider):
  28. self.client. close()
  29. # 下载图片
  30. class ImagePipeline(ImagesPipeline):
  31. def file_path(self, request, response=None, info=None):
  32. url = request.url
  33. file_name = url.split( '/')[ -1]
  34. return file_name
  35. def item_completed(self, results, item, info):
  36. image_paths = [x[ 'path'] for ok, x in results if ok]
  37. if not image_paths:
  38. raise DropItem( 'Image Downloaded Failed')
  39. return item
  40. def get_media_requests(self, item, info):
  41. yield Request(item[ 'url'])

scrapy.setting 设置


   
  1. # -*- coding: utf -8 -*-
  2. # Scrapy settings for images project
  3. BOT_NAME = 'images' # 其实就是爬虫的名字
  4. SPIDER_MODULES = [ 'images.spiders'] # 爬虫模块
  5. NEWSPIDER_MODULE = 'images.spiders' # 爬虫的命名空间
  6. # Crawl responsibly by identifying yourself (and your website) on the user-agent
  7. 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
  8. # Obey robots.txt rules
  9. ROBOTSTXT_OBEY = True # 遵循爬虫规则
  10. # 抓取最大页数
  11. MAX_PAGE = 50 # 设置爬取最大页码
  12. # MONGO信息设置
  13. MONGO_URI = 'localhost' # 本地数据库 uri
  14. MONGO_PORT = 27017 # 数据库端口
  15. MONGO_DB = 'images' # 数据库名字
  16. # 图片下载路径
  17. IMAGES_STORE = './image1' # 图片存储路径
  18. # Obey robots.txt rules
  19. ROBOTSTXT_OBEY = False
  20. DOWNLOAD_DELAY = 2 # 延迟
  21. # The download delay setting will honor only one of:
  22. # See https: //doc.scrapy.org/en/latest/topics/downloader-middleware.html
  23. DOWNLOADER_MIDDLEWARES = { # 刚刚我们编写的随机 agent 中间件就在这里引用说明了,数字为权限级别
  24. 'images.middlewares.RandomUserAgentMiddelware': 543,
  25. }
  26. ITEM_PIPELINES = { # 管道权限声明
  27. 'images.pipelines.ImagePipeline': 300,
  28. 'images.pipelines.MongoPipeline': 301,
  29. }

到此为止,我们的爬虫实际上已经完成了,所谓欲成大事,只欠东风来助一臂之力了,就是运行代码了

scrapy crawl images

当当当,好多美女啊


转载:https://blog.csdn.net/qq_36772866/article/details/105803786
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场