未分类

DownloaderMiddlewares(下载器中间件)Scarpy的新版本能自动生成下载器中间件,一般不用自己去重写下载器中间件是引擎和下载器之间通信的中间件。在这个中间件中我们可以设置代理、更换请求头等来达到反反爬虫的目的。要写下载器中间件,可以在下载器中实现两个方法..process_request(self,request,spider):这个方法是在请求发送之前会执行process_response(self,request,response,spider),这个方法是数据下载到引擎之前执行process_request(self,request,spider)这个方法是在请求发送之前会执行参数:request:发送请求的request对象。spider:发送请求的spider对象返回值:已经激活中间件,process_response()方法则会在每个response返回时被调用。返回None:Scrapy将继续处理该请求,执行其他中间件中的相应方法,直到合适的下载器处理函数被调用。返回Response对象:Scrapy将不会调用任何其他的process.request方法,将直接返回这个response对象。返回Request对象:不再使用之前的request对象去下载数据,而是根据现在返回的request对象返回数据。如果这个方法中抛出了异常,则会调用process.exception方法。process_response(self,request,response,spider)这个方法是在收到相应时执行参数:request:request对象。response:待处理的response对象。spider:splder对象。返回值:返回Response对象:会将这个新的Response对象传给其他中间件处理。返回Request对象:下载器链被切断,返回的Request会重新被下载器调度请求。如果抛出一个异常,那么调用request的errback方法,如果没有指定这个方法,那么会抛出一个异常。随机请求头请求头网站:http://www.useragentstring.com/pages/useragentstring.php?typ=Browser开启下载中间件#Enableordisabledownloadermiddlewares#Seehttps://docs.scrapy.org/en/latest/topics/downloader-middleware.htmlDOWNLOADER_MIDDLEWARES={'headersApp.middlewares.HeadersappDownloaderMiddleware':543,}设置随机请求头在middlewares.py里编辑DownloaderMiddleware()类classHeadersappDownloaderMiddleware(object):HEADERS=['Mozilla/5.0(iPhone;CPUiPhoneOS11_0likeMacOSX)AppleWebKit/604.1.38(KHTML,likeGecko)Version/11.0Mobile/15A372Safari/604.1','Mozilla/5.0(WindowsNT6.1;WOW64;rv:40.0)Gecko/20100101Firefox/40.1','Mozilla/5.0(WindowsNT6.1;WOW64;Trident/7.0;AS;rv:11.0)likeGecko','Mozilla/5.0(Windows;U;WindowsNT5.1;en-US;rv:1.9.2.21pre)GeckoK-Meleon/1.7.0','Mozilla/4.0(compatible;MSIE6.0;WindowsXP5.1)Lobo/0.98.4','Mozilla/5.0(Windows;U;WindowsNT6.1;en-US;rv:1.9.2.28)Gecko/20120410Firefox/3.6.28']defprocess_request(self,request,spider):importrandomrequest.headers['User-Agent']=random.choice(self.HEADERS)returnNone关于换IP看这里

未分类

讯代理动态转发#讯代理动态转发源码importrequestsimporthashlibimporttimeclassIP(object):def__init__(self,orderno,secret):self.orderno=ordernoself.secret=secretdefHeaders(self):timestamp=str(int(time.time()))#计算时间戳planText='orderno='+self.orderno+','+'secret='+self.secret+','+'timestamp='+timestamp#‘订单号’‘接口’‘时间戳’拼接出字符串string=planText.encode()#需要MD5加密需要转码md5_string=hashlib.md5(string).hexdigest()#planText拼接出的字符串进行MD5()sign=md5_string.upper()#转成大写auth='sign='+sign+'&'+'orderno='+self.orderno+'&'+'timestamp='+timestamp#‘加密的字符串’‘订单号’‘时间戳’拼接字符串headers=auth#认证的头部returnheadersif__name__=='__main__':#注意不同的网站,修改不同的httpip=IP('订单号','secret')proxy={'http':'http://forward.xdaili.cn:80'}headers={'Proxy-Authorization':ip.Headers()}print(headers)r=requests.get(url="http://httpbin.org/ip",headers=headers,proxies=proxy).json()print(r)随机IP开启下载中间件#Enableordisabledownloadermiddlewares#Seehttps://docs.scrapy.org/en/latest/topics/downloader-middleware.htmlDOWNLOADER_MIDDLEWARES={'IpApp.middlewares.IpappDownloaderMiddleware':543,}Spider源码classIpspiderSpider(scrapy.Spider):name='ipSpider'allowed_domains=['httpbin.org']start_urls=['http://httpbin.org/ip']defparse(self,response):print(response.text)yieldRequest(url=self.start_urls[0],dont_filter=True)设置随机IP在middlewares.py里编辑DownloaderMiddleware()类fromIpApp.xundailiimportIPclassIpappDownloaderMiddleware(object):defprocess_request(self,request,spider):ip=IP('订单号','secret')headers=ip.Headers()proxy='http://forward.xdaili.cn:80'request.headers['Proxy-Authorization']=headersrequest.meta['proxy']=proxyreturnNone测试结果小错误提示当使用认证类代理是出现找不到Proxy-Authorization的头部信息原因:scrapy会自动去掉Proxy-Authorization解决:进入scrapy的源码路径:scrapy\core\downloader\handlers\http11.py注释掉:#ifisinstance(agent,self._TunnelingAgent):#headers.removeHeader(b'Proxy-Authorization')或者使用框架提供的下载中间件```关于下载中间件的了解

未分类

说明上一个案例,对自带的ImagePipeline写了一个图片下载案例,现在对最后的小结进行改进对图片进行进行自定义名称存储主要涉及ImagePipeline类的继承与方法的重写优化开始优化Wallpaperspider.py文件defparse(self,response):#循环li标签forurltaginresponse.xpath('//ul[@class="clearfix"]/li/a'):#获取图片标题titles=urltag.xpath('./img/@alt').get()#获取图片链接url=urltag.xpath('./img/@src').get()#-->没有http://的链接urls_pic=response.urljoin(url)#拼接URL#传给数据ItemyieldImagesappItem(titles=titles,image_urls=urls_pic)优化pipeline.py文件继承ImagePipeline类导入ImagesPipeline类fromscrapy.pipelines.imagesimportImagesPipeline继承ImagesPipeline类classPicImagesPipeline(ImagesPipeline):pass重写get_media_requests()方法此方法是构造请求的Ruquest对象#构造下载,首先调用的函数defget_media_requests(self,item,info):#导入Request模块fromscrapy.http.requestimportRequest#在item中取出url,再把item给meta参数进行传递#在后面方法中,可以从request对象的meta属性获得item的数据yieldRequest(url=item['image_urls'],meta={'item':item})重写file_path()方法此方法是返回存储的路径deffile_path(self,request,response=None,info=None):#从request对象的meta属性获取titletitle=request.meta['item']['titles']#构造存储路径path=title+'.jpg'returnpath修改settings.py文件因为使用了自定义的Pipeline,所以我们需要指定我们重写的Pipeline#Configureitempipelines#Seehttps://docs.scrapy.org/en/latest/topics/item-pipeline.htmlITEM_PIPELINES={'ImagesApp.pipelines.PicImagesPipeline':1,#继承的重写ImagesPipeline类}运行爬虫scrapycrawlWallPaperSpider

未分类

使用官方提供的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类,然后重新里面的相关方法,可以查看改进版。

未分类

案例效果涉及的重要知识当前标签的索引获取index()HTML代码<divclass="wrapper"><ulid="left"><li><ahref="#">女靴</a></li><li><ahref="#">雪地靴</a></li><li><ahref="#">冬裙</a></li><li><ahref="#">呢大衣</a></li><li><ahref="#">毛衣</a></li><li><ahref="#">棉服</a></li><li><ahref="#">女裤</a></li><li><ahref="#">羽绒服</a></li><li><ahref="#">牛仔裤</a></li></ul><ulid="center"><li><ahref="#"><imgsrc="img/女靴.jpg"/></a></li><li><ahref="#"><imgsrc="img/雪地靴.jpg"/></a></li><li><ahref="#"><imgsrc="img/冬裙.jpg"/></a></li><li><ahref="#"><imgsrc="img/呢大衣.jpg"/></a></li><li><ahref="#"><imgsrc="img/毛衣.jpg"/></a></li><li><ahref="#"><imgsrc="img/棉服.jpg"/></a></li><li><ahref="#"><imgsrc="img/女裤.jpg"></a></li><li><ahref="#"><imgsrc="img/羽绒服.jpg"/></a></li><li><ahref="#"><imgsrc="img/牛仔裤.jpg"/></a></li><li><ahref="#"><imgsrc="img/女包.jpg"/></a></li><li><ahref="#"><imgsrc="img/男包.jpg"/></a></li><li><ahref="#"><imgsrc="img/登山鞋.jpg"/></a></li><li><ahref="#"><imgsrc="img/皮带.jpg"/></a></li><li><ahref="#"><imgsrc="img/围巾.jpg"/></a></li><li><ahref="#"><imgsrc="img/皮衣.jpg"/></a></li><li><ahref="#"><imgsrc="img/男毛衣.jpg"/></a></li><li><ahref="#"><imgsrc="img/男棉服.jpg"/></a></li><li><ahref="#"><imgsrc="img/男靴.jpg"/></a></li></ul><ulid="right"><li><ahref="#">女包</a></li><li><ahref="#">男包</a></li><li><ahref="#">登山鞋</a></li><li><ahref="#">皮带</a></li><li><ahref="#">围巾</a></li><li><ahref="#">皮衣</a></li><li><ahref="#">男毛衣</a></li><li><ahref="#">男棉服</a></li><li><ahref="#">男靴</a></li></ul></div>CSS代码*{margin:0;padding:0;font-size:12px;}ul{list-style:none;}a{text-decoration:none;}.wrapper{width:298px;height:248px;margin:100pxauto0;border:1pxsolidpink;overflow:hidden;}#left,#center,#right{float:left;}#leftli,#rightli{background:url(../img/lili.jpg)repeat-x;}#leftlia,#rightlia{display:block;width:48px;height:27px;border-bottom:1pxsolidpink;line-height:27px;text-align:center;color:black;}#leftlia:hover,#rightlia:hover{color:#fff;background-image:url(../img/abg.gif);}#center{border-left:1pxsolidpink;border-right:1pxsolidpink;}img{width:200px;height:250px;}JS代码$(function(){//绑定左边的li标签鼠标属性$('#leftli').mouseover(function(){//获取当前li标签索引varindex=$(this).index();//展示相应索引图片$('#centerli').eq(index).show();//隐藏其他图片$('#centerli').eq(index).siblings('li').hide()//链式写法$('#centerli').eq(index).show().siblings('li').hide();});//绑定右边的li标签鼠标属性$('#rightli').mouseover(function(){//获取鼠标当前索引9是左边的图片是9开始的varindex=$(this).index()+9;//展示相应索引图片$('#centerli').eq(index).show();//隐藏其他索引图片$('#centerli').eq(index).siblings('li').hide()//链式写法$('#centerli').eq(index).show().siblings('li').hide();})})案例图片下载:淘宝服饰案例

2019-12-1 1220 0
未分类

效果CSS代码*{padding:0;margin:0;}ul{list-style-type:none;margin:100px;}.menu-head{width:185px;height:47px;line-height:47px;padding-left:38px;font-size:17px;color:#475052;cursor:pointer;border:1pxsolid#e1e1e1;position:relative;margin:0px;font-weight:bold;background:#f1f1f1centerrightno-repeat;}.menu-list.current{background:#f1f1f1centerrightno-repeat;}.menu-body{width:223px;height:auto;overflow:hidden;line-height:38px;border-left:1pxsolid#e1e1e1;backguound:#fff;border-right:1pxsolid#e1e1e1;display:none;}.menu-bodya{display:block;width:223px;height:38px;line-height:38px;padding-left:38px;color:#777;background:#fff;text-decoration:none;border-bottom:1pxsolid#e1e1e1;}HTML代码<body><ulclass="menu-list"><li><pclass="menu-head">目标管理</p><divclass="menu-body"><ahref="#">主题空间</a><ahref="#">项目任务</a><ahref="#">工作计划</a><ahref="#">日程事件</a><ahref="#">时间视图</a></div></li><li><pclass="menu-head">会议管理</p><divclass="menu-body"><ahref="#">主题空间</a><ahref="#">会议安排</a><ahref="#">待开会议</a><ahref="#">已开会议</a><ahref="#">会议资源</a></div></li><li><pclass="menu-head">知识社区</p><divclass="menu-body"><ahref="#">我的收藏</a><ahref="#">知识广场</a><ahref="#">文档中心</a><ahref="#">我的博客</a><ahref="#">文档库管理</a></div></li></ul></body>JS代码第一代$(function(){//鼠标经过$('.menu-head').mouseover(function(){//$(this)JQuery当前元素//查找当前元素的,同级元素$(this).siblings('.menu-body').show()})//鼠标离开$('.menu-head').mouseout(function(){//$(this)JQuery当前元素$(this).siblings('.menu-body').hide()})})JS代码第二代利用hover()函数,合并鼠标的经过与离开的事件hover([over,]out)参数:over:鼠标移到元素上要触发的函数out:鼠标移出元素要触发的函数//组合写法$('.menu-head').hover(//鼠标经过function(){$(this).siblings('.menu-body').slideDown()},//鼠标离开function(){$(this).siblings('.menu-body').slideUp()});JS代码第三代利用hover()函数,合并鼠标的经过与离开的事件hover([over,]out)只写一个参数,代表无论鼠标经过还是鼠标退出,都要执行这个函数//组合写法$('.menu-head').hover(//鼠标事件,切换滑动function(){$(this).siblings('.menu-body').slideToggle()})

未分类

数组遍历方法:forEach()原生JS方法原生的JSforEach()不能遍历伪数组vara=[11,12,13,14,15,16];//遍历数组,但不能遍历伪数组,一个回调函数a.forEach(function(value,index){console.log(value,index);});数组遍历方法:each()JQuery静态方法JQueryeach()静态方法,可以遍历数组,也可以遍历伪数组//伪数组就是一个对象varb={'a':1,'b':2,'c':3,'d':4,length:4};//使用JQuery的each静态方法遍历伪数组$.each(b,function(index,value){console.log(index,value);})数组遍历方法:map()原生JS方法与foeEach()函数一样,不能遍历伪数组map(function(值,索引,该数组){})vara=[11,12,13,14,15,16];a.map(function(value,index,array){console.log(value,index,array);});数组遍历方法:map()JQuery静态方法JQuerymap()静态方法,可以遍历数组,也可以遍历伪数组varb={1:1,2:2,3:3,4:4,length:4};res=$.map(b,function(value,index){returnvalue+index});console.log(res)map()函数的作用是:遍历数组,然后对数组的值进行操作,返回一个新的数组trim()作用:去除字符串前后的空格参数:需要去除的字符串返回值:去除后的字符串vara='aaa';console.log("---"+a+"---");varres=$.trim(a);console.log(res)isWindow()作用:判断传入的参数是否是Window是否是Window对象参数:需要判断的对象返回值:true/false//真数组vararr=[1,2,3,4,5,6];//伪数组vararrlike={0:1,1:3,2:5,3:6,4:7,length:5};//对象varobj={"name":"aaa","age":5};//函数varfn=function(){};//window对象varw=window;varres=$.isWindow(w);console.log(res);isArray()作用:判断传入的参数是否是真数组参数:需要判断的对象返回值:true/false//真数组vararr=[1,2,3,4,5,6];//伪数组vararrlike={0:1,1:3,2:5,3:6,4:7,length:5};//对象varobj={"name":"aaa","age":5};//函数varfn=function(){};//window对象varw=window;varres=$.isArray(w);console.log(res);isFunction()作用:判断传入的参数是否是函数参数:需要判断的对象返回值:true/falsevarres=$.isFunction($);console.log(res);//-->true说明JQuery本质上是一个函数

2019-12-1 823 0
未分类

jQuery基础选择器名称用法描述ID选择器$("#id")获取指定ID的元素类选择器$(".class")获取同一类的class的元素标签选择器$("div")获取同一类标签的所有元素全选选择器$("*")匹配所有元素并集选择器$("div,p,li")选取多个元素交集选择器$("li.current")交集元素jQuery层级选择器名称用法描述子代选择器$("ul>li");使用>查找下一级标签,不会获取孙子层元素后代选择器$("ulli");使用空格,代表获取ul下的所有li元素,包括孙子等jQuery筛选选择器语法用法描述:first$("li:first")选择第一个li标签:last$("li:last")选择最后一个li标签:eq(index)$("li:eq(0)")选择索引为0的li标签:odd$("li:odd")选择索引为奇数的li标签:even$("div,p,li")选择索引为偶数的li标签jQuery筛选方法selector代表选择器的意思语法用法描述parent()$("li").parent()查找父级元素children(selector)$("ul").children("li")相当于$("ul>li"),最近的一级find()$("ul").find("li")相当于后代选择器$("ulli")siblings(selector)$(".first").siblings("li")查找同级的li标签nextAll([expr])$("div").nextAll()查找当前元素之后的所有同级元素prevAll([expr])$("div").prevtAll([expr])查找当前元素之前的所有同级元素hasClass(class)$("divi").hasClass('pro')检查某个标签是否包含某个特定的class,有返回trueeq(index)$("div").eq(0)相当于$("div:eq(0)")标签过滤器小例子//查找div下的第一个li,设置为pink色$("divli:first").css("color","pink");//查找同级的所有标签$("span").siblings()//查找同级的所有标签$("span").siblings()

未分类

登录数据库Mysql为了安全,默认不允许远程用户root登录mysql-p[]-u[]-p[]mysql-hlocalhost-uroot-p参数作用-h主机地址:-p127.0.0.1:3306-u用户名:-uroot-p密码:-p密码查看数据库showdatabases;进入数据库use[数据库名];查看数据库的全部表第一种方法:首先要进入数据库:use[数据库名];然后查看表:showtables;第二种方法:直接查看showtablesfrom[数据库名];查看当前操作的数据库selectdatabase();mysql>selectdatabase();+------------+|database()|+------------+|news|+------------+1rowinset(0.00sec)创建数据库createdatabase[数据库名];删除数据库dropdatabaes[数据库名];退出Mysqlexitmysql>exitByeC:\Users\ASUS>打开数据库登录MySQL后,需要对数据库进行操作,例如查询、创建表等。需要先用use命令打开相应数据库,才能对该数据库进行后续操作。use[数据库名];mysql>usenews;Databasechangedmysql>创建数据库表打开相应数据库后,才能进行这项操作,最后一个字段不写逗号createtable[表名]([字段名1][类型1][类型2],[字段名2][类型1][类型2],....);createtablestudent(idint(4)primarykeyauto_increment,namechar(20)notnull,sexint(4)notnulldefault'0'#不写逗号);删除数据库表droptables[表名];droptablesstudent;查看MySQL的版本第一种方法:mysql>selectversion();+------------+|version()|+------------+|5.6.43-log|+------------+1rowinset(0.01sec)第二种方法:在CMD执行:mysql--version或者mysql-VC:\Users\ASUS>mysql--versionmysqlVer14.14Distrib5.6.43,forWin64(x86_64)

2019-11-21 818 1