Python极客

使用官方提供的PiplineScrapy框架为下载的item中包含的图片提供了一个可以重用的图片下载pipeline。这些pipeline有共同的方法和结构。一般会使用到有FilesPipeline、ImagesPipline。使用官方Pipline的好处避免重新下载最近已经下载的数据方便指定下载的路径方便的转换图片的格式方便生成略缩图方便检测图片的宽高,确保满足最小值异步下载,效率非常高ImagesPipline的使用准备使用ImagesPipline,需要提前下载好Pillow图片处理库当使用ImagesPipline下载图片的时候,按照以下步骤完成1.定义Item属性必须要定义两个个默认的item属性:image_urls:存储下载图片的链,需要传递一个列表。images:文件下载完成后,会把图片的相关信息存储到这个属性里,比如下载的路径、下载的URL、文件的校验码…classMaybachItem(scrapy.Item):image_urls=scrapy.Field()images=scrapy.Field()2.启用ImagesPipline管道在settings.py里开启#Configureitempipelines#Seehttps://docs.scrapy.org/en/latest/topics/item-pipeline.htmlITEM_PIPELINES={#'Maybach.pipelines.MaybachPipeline':300,#开启图片下载器'scrapy.pipelines.images.ImagesPipeline':1,}3.配置ImagesPipline下载路径在settings.py里添加上#ImagesPipline下载路径,可以使用OS模块来指定路径#没有这个路径,会自动创建IMAGES_STORE='路径'0x00创建爬虫工程scrapystartprojectImagesApp(创建Scrapy工程)cdImagesApp(进入工程目录)scrapygenspiderWallPaperSpiderpic.netbian.com(创建爬虫)0x01配置爬虫关闭机器人协议#Obeyrobots.txtrulesROBOTSTXT_OBEY=False设置请求头#Crawlresponsiblybyidentifyingyourself(andyourwebsite)ontheuser-agentUSER_AGENT='Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/76.0.3809.100Safari/537.36'开启ImagesPipline管道#Configureitempipelines#Seehttps://docs.scrapy.org/en/latest/topics/item-pipeline.htmlITEM_PIPELINES={#'ImagesApp.pipelines.ImagesappPipeline':300,(注释掉)'scrapy.pipelines.images.ImagesPipeline':1,}配置图片的下载路径importosIMAGES_STORE=os.path.join(os.path.dirname(os.path.dirname(__file__)),'img')设置Item属性在items.py里classImagesappItem(scrapy.Item):#definethefieldsforyouritemherelike:#name=scrapy.Field()image_urls=scrapy.Field()images=scrapy.Field()0x02编写爬虫程序通过对网页的分析,我们需要的链接在这些li标签下获取图片链接但这些url,没有协议头defparse(self,response):url=response.xpath('//ul[@class="clearfix"]/li/a/img/@src').getall()print(url)添加协议头response.urljoin(url)方法会自动把相应的协议头加上urls_pic=list(map(lambdaurl:response.urljoin(url),urls))把图片链接通过Item传给ImagesPipeline下载导入ImagesappItem,传入url列表,启动爬虫fromImagesApp.itemsimportImagesappItemdefparse(self,response):urls=response.xpath('//ul[@class="clearfix"]/li/a/img/@src').getall()urls_pic=list(map(lambdaurl:response.urljoin(url),urls))yieldImagesappItem(image_urls=urls_pic)#启动爬虫scrapycrawlWallPaperSpider0x03小结这个小案例是直接使用的官方的ImagePipeline下载,所以没有对图片进行重命名,或者分类等操作,需要实现这些操作,就需要继承ImagesPipeline类,然后重新里面的相关方法,可以查看改进版。

Python极客

迭代器迭代器就是可以使用for循环的对象,list、str、tuple….那怎样才能实现这样的迭代?nums=[12,13,14]strs="python"tuples=(1,2,3,4,5)fornuminnums:print(num)一个对象可迭代的条件需要这个对象有__iter__()方法classClassmate(object):#有了这个方法该类就是可迭代的def__iter__(self):pass添加一个列表和添加方法给Classmate类classClassmate(object):def__init__(self):#存储self.namesList=list()defadd(self,other):#添加到列表里self.namesList.append(other)#有了这个方法该类就是可迭代的def__iter__(self):pass迭代器一个对象有__iter__()和__next__()方法叫迭代器如果使该对象可以返回迭代的数据:就需要一个迭代器的__next__()方法定义一个迭代器类classClassIterator(object):def__iter__(self):passdef__next__(self):pass完善一个可以执行的迭代器迭代对象的__iter__()方法需要返回一个迭代器对象#可迭代对象classClassmate(object):def__init__(self):self.namesList=list()defadd(self,other):self.namesList.append(other)#有了这个方法该类就是可迭代的def__iter__(self):#需要反对一个迭代器对象#把self传给迭代器,使迭代器可以获取self.namesListreturnClassIterator(self)#迭代器对象classClassIterator(object):def__init__(self,obj):self.nameList=obj.namesList#记录循环的次数self.count=0def__iter__(self):passdef__next__(self):ifself.count<len(self.nameList):name=self.nameList[self.count]self.count+=1returnnameelse:#自定义一个异常停止循环raiseStopIteration#主函数classmate=Classmate()#实例化对象classmate.add("小小")classmate.add("大大")classmate.add("中中")#for循环对象fornameinclassmate:print(name)把迭代对象类和迭代器类合并迭代对象和迭代器是两个类,那是否可以合并classClassmate(object):def__init__(self):self.namesList=list()self.count=0defadd(self,other):self.namesList.append(other)#有了这个方法该类就是可迭代的def__iter__(self):#需要反对一个迭代器对象#把列表传给迭代器returnselfdef__next__(self):ifself.count<len(self.namesList):name=self.namesList[self.count]self.count+=1returnnameelse:#自定义一个异常停止循环raiseStopIteration

Python极客

CrawlSpider简介Spider可以做很多爬虫了,但是CrawlSpider是为全站爬取而生创建CrawlSpider爬虫工程scrapystartprojectwxapp创建CrawlSpider爬虫scrapygenspider-tcrawl[爬虫名称][爬取网站的域名]scrapygenspider-tcrawlwxapp_spiderwxapp-union.com修改settings.py设置#设置user-agent#Crawlresponsiblybyidentifyingyourself(andyourwebsite)ontheuser-agentUSER_AGENT=''#关闭机器人协议#Obeyrobots.txtrulesROBOTSTXT_OBEY=False#设置延迟#Configureadelayforrequestsforthesamewebsite(default:0)#Seehttps://docs.scrapy.org/en/latest/topics/settings.html#download-delay#SeealsoautothrottlesettingsanddocsDOWNLOAD_DELAY=1#设置headers#Overridethedefaultrequestheaders:DEFAULT_REQUEST_HEADERS={'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language':'en',}#开启pipelines文件写入#Configureitempipelines#Seehttps://docs.scrapy.org/en/latest/topics/item-pipeline.htmlITEM_PIPELINES={'wxapp.pipelines.WxappPipeline':300,}制定Items传输打开items.pyclassWxappItem(scrapy.Item):#definethefieldsforyouritemherelike:#name=scrapy.Field()#文章标题title=scrapy.Field()#文章内容article=scrapy.Field()编写获取页面和文章链接的规则进入/spiders目录,查看wxapp_spider.py的爬虫类是继承于CrawlSpider类可在rules=()里定义多个Rule()规则Rule()参数详解:LinkExtractor(allow=r’匹配规则’):指定在页面里匹配链接的规则,支持正则表达式callback=’函数名称’:匹配到链接所执行的函数follow=True:爬取了匹配的页面后,是否在匹配页面再进行匹配(可实现翻页操作)name='wxapp_spder'allowed_domains=['www.wxapp-union.com']start_urls=['http://www.wxapp-union.com/portal.php?mod=list&catid=1&page=1']rules=(#设置匹配页数的规则(可以设置多个匹配连接的Rule())Rule(#页数的连接的匹配规则(支持正则表达式)LinkExtractor(allow=r'.+mod=list&catid=1&page=\d+'),#匹配到链接进行解析的函数follow=True),#匹配文章页面链接Rule(#匹配文章链接LinkExtractor(r'http://www.wxapp-union.com/article-(.*)-(.*)\.html'),#匹配到文章链接的解析函数callback='parse_article',follow=False,))添加解析文章页面的函数parse_article()导入fromwxapp.itemsimportWxappItemdefparse_item(self,response):pass#print(response.url)defparse_article(self,response):title=response.xpath('//div[@class="hhmcl"]/div/h1/text()').get()articleList=response.xpath('//td[@id="article_content"]//text()').getall()article="".join(articleList).split()#拼接返回的列表,去除前后空白字符yieldWxappItem(title=title,article=article)存储爬取数据打开pipeline.py文件导入fromscrapy.exportersimportJsonLinesItemExporter模块classWxappPipeline(object):defopen_spider(self,spider)::#以二进制方式打开文件self.ft=open('articleInfo.json','wb')self.exporter=JsonLinesItemExporter(self.ft,ensure_ascii=False,encoding='utf-8')defclose_spider(self,spider):self.ft.close()defprocess_item(self,item,spider):self.exporter.export_item(item)returnitem运行爬虫scrapycrawlwxapp_spider