作为一名爬虫爱好者,虽然requests库已经足够我们做一些简单的小爬虫,selenium能帮助我们模仿浏览器行为,但学会使用框架能帮助我们更加便捷高效的完成爬取任务。
案例分析:爬取宝马五系汽车图片
1.新建一个爬虫项目
scrapy startproject bw
cd bw
scrapy genspider bw5 "XXXXXXX域名"
2.在item.py中创建三个容器
import scrapy
class BwItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field() #装子分类名字
image_urls = scrapy.Field() #装图片链接
images = scrapy.Field()
3.在爬虫文件bw5.py中导入BwItem并解析网页
import scrapy
from bw.items import BwItem
class Bw5Spider(scrapy.Spider):
name = 'bw5'
allowed_domains = ['car.autohome.com.cn']
start_urls = ['https://car.autohome.com.cn/pic/series/65.html']
def parse(self, response):
uiboxs = response.xpath("//div[@class='uibox']")[1:]
for uibox in uiboxs:
title = uibox.xpath(".//div[@class='uibox-title']/a/text()").get()
urls = uibox.xpath(".//div[@class='uibox-con carpic-list03']/ul/li/a/img/@src").getall()
# for x in urls:
# url = response.urljoin(x)
# print(url)
#获取所有图片url
urls = list(map(lambda url:response.urljoin(url),urls))
item = BwItem(title=title,image_urls=urls)
yield item
4.scrapy框架中帮我们写好了异步下载程序,只需按步骤打开下载器开关配置相应路径即可
当使用File Pipeline下载文件的时候,按照以下步骤来完成:
1.定义好一个Item,然后在这个item中定义两个属性,分别为file_urls以及files 。file_urls是用来存储需要下载的文件的url链接,需要一个列表
⒉.当文件下载完成后,会把文件下载的相关信息存储到item的files属性中。比如下载路径、下载的url和文件的校验码等。
3.在配置文件 settings.py中配置FILEs_STORE,这个配置是用来设置文件下载下来的路径。
4.启动pipeline在ITEN_PIPELNES中设置scrapy.pipelines.files.FilesPipeline:1.
下载图片的Images Pipeline:
1.定义好一个Item,然后在这个item中定义两个属性,分别为image_urls以及images 。image_urls是用来存储需要下载的文件的url链接,需要一个列表
⒉.当文件下载完成后,会把文件下载的相关信息存储到item的images属性中。比如下载路径、下载的url和文件的校验码等。
3.在配置文件 settings.py中配置IMAGES_STORE,这个配置是用来设置文件下载下来的路径。
4.启动pipeline在ITEN_PIPELNES中设置scrapy.pipelines.images.ImagesPipeline:1
若有下载要求,需要在pipelines.py中重写相关方法
import os
from urllib import request
from scrapy.pipelines.images import ImagesPipeline
from bw import settings
class BwImagesPipeline(ImagesPipeline):#继承父类ImagesPipeline
def get_media_requests(self, item, info):#重写父类方法
request_objs = super(BwImagesPipeline,self).get_media_requests(item,info)
for request_obj in request_objs:
request_obj.item = item
return request_objs
def file_path(self, request, response=None, info=None):
path = super(BwImagesPipeline,self).file_path(request,response,info)
title = request.item.get("title")
images_store = settings.IMAGES_STORE
title_path = os.path.join(images_store,title)
if not os.path.exists(title_path):
os.mkdir(title_path)
image_name = path.replace("full/","")
image_path = os.path.join(title_path,image_name)
return image_path
5.在setting.py中开启相关设置
# Obey robots.txt rules
ROBOTSTXT_OBEY = False #关闭机器人协议
#设置默认请求头
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/84.0.4147.89 Safari/537.36',
}
#开启item_pipelines
ITEM_PIPELINES = {
# 'bw.pipelines.BwPipeline': 300,
# 'scrapy.pipelines.images.ImagesPipeline':1,
'bw.pipelines.BwImagesPipeline':1,
}
#图片下载路径,供image pipelines使用
IMAGES_STORE = os.path.join(os.path.dirname(os.path.dirname(__file__)),'images')
6.在工程目录下创建start.py文件以启动爬虫
from scrapy import cmdline
cmdline.execute("scrapy crawl bw5".split())