最近在学习爬虫,学完后想实践一下,所以现在准备爬取校花网的一部分图片
第一步,导入需要的库
from urllib import request #用于处理request请求和获得响应 from urllib import error #异常处理 from lxml import etree #用于解析html
第二步,进行简单的身份伪装
def setting_User_Agent(url): ''' 有的网站会限制爬虫访问,所以可以通过 设置User-Agent来伪装成一个浏览器 ''' headers = {} headers['User-Agent'] = 'Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3' return request.Request(url, headers=headers)
第三步,观察我们想要访问的网站,并得到前十个页面的url
这是第一页的url:http://www.xiaohuar.com/list-1-0.html
这是第二页的url:http://www.xiaohuar.com/list-1-1.html
这是第四个页面的url:http://www.xiaohuar.com/list-1-3.html
所以我们可以通过一个函数来获得前十页的url
def getPageUrl(): ''' 获得前十页的url ''' url = "http://www.xiaohuar.com/list-1-" pagrUrlList = [] for i in range(10): pageUrl = url + str(i) + ".html" pagrUrlList.append(pageUrl) return pagrUrlList
第四步、假如我们已经知道了一张图片的名称和路径,那我们可以编写代码来实现自动根据路径下载图片,代码如下
def getIMg(name,imgUrl): # 文件的路径和文件名称 name = "D:/xiaohua/" + name + ".jpg" #发送请求并获得响应 try: rsp = request.urlopen(imgUrl) #把文件写进指定路径 with open(name,"wb") as f: f.write(rsp.read()) except: print("发生了一个错误")
第五步、查看网页布局
当进入网页后,按F12或者Fn + F12,会看到如下界面
当你鼠标放在右边的一个div上时,左边页面颜色会发生变化,打开你想要查看的div,一直往下找,直到出现下图
第六步:
1、我们现在知道了,图片信息就在<img>标签下,alt的属性值就是名字,src的属性值就是图片的地址,所以接下来编写代码获取名字和图片地址
2、获得的名字和图片地址传入getImg()函数,代码如下
def getImgUrl(url): # 1、进行User-Agent的伪装 #url = setting_User_Agent(url) #2、发起请求 try: rsp = request.urlopen(url) except: print("发生错误") # 3、返回的是一个Rs类型的数据,需要转化为bytes类型 html = rsp.read() # 4、把bytes类型的数据放入lxml的etree中,方便用xpath解析 tree = etree.HTML(html) # 5、用xpath解析html aList = tree.xpath('//div[@class = "img"]/a') ''' aList = tree.xpath('//div[@class = "img"]/a') 此代码的意思是:首先找到一个有class属性,并且属性值为img 的div标签,再获得该标签下的a标签 ''' # 6 、获得a标签下的img标签的alt属性和src属性,同样用xpath for a in aList: name = str(a.xpath('./img/@alt')) imgUrl = str(a.xpath('./img/@src')) ''' 此时获得的name和imgUrl并不是标准的格式,而是 ['*****************']这样的,所以需要用字符串截取 ''' name = name[2:-2] imgUrl = imgUrl[2:-2] ''' 该网站的图片标准链接是以http开头的,而获取的imgUrl有的缺失了 一部分,所以加一个判断,如果没有,就加上 ''' t = imgUrl[:4] if t == "http": imgUrl = imgUrl else: imgUrl = "http://www.xiaohuar.com" + imgUrl # 通过nema 和 imgUrl下载图片 getIMg(name, imgUrl) return None
现在,该写的差不多已经写完了,把代码整合一下:
if __name__ == '__main__': pageUrls = getPageUrl() for pageUrl in pageUrls: getImg(pageUrl)
代码执行前
执行后
整个爬取过程90秒,爬取了几百张图片,比下载快多了
总结:
我的代码能力和逻辑思维还不够,代码不够简洁,写文件那块做的不好,非常耗费资源,
可改进的地方:
1、相同功能的代码可以提取出来单独写一个函数
2、异常处理没写好,可以处理的更加完善
3、频繁的打开和关闭文件很耗资源,可以在程序开始时打开文件,程序结束时关闭文件
完整的代码如下:
from urllib import request #用于处理request请求和获得响应 from urllib import error #异常处理 from lxml import etree #用于解析html def setting_User_Agent(url): ''' 有的网站会限制爬虫访问,所以可以通过 设置User-Agent来伪装成一个浏览器 ''' headers = {} headers['User-Agent'] = 'Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3' return request.Request(url, headers=headers) def getPageUrl(): ''' 获得前十页的url ''' url = "http://www.xiaohuar.com/list-1-" pagrUrlList = [] for i in range(10): pageUrl = url + str(i) + ".html" pagrUrlList.append(pageUrl) return pagrUrlList def getIMg(name,imgUrl):# 根据名字和图片链接下载图片 # 文件的路径和文件名称 name = "D:/xiaohua/" + name + ".jpg" #发送请求并获得响应 try: rsp = request.urlopen(imgUrl) #把文件写进指定路径 with open(name,"wb") as f: f.write(rsp.read()) except: print("发生了一个错误") return None def getImg(url): # 1、进行User-Agent的伪装 url = setting_User_Agent(url) #2、发起请求 try: rsp = request.urlopen(url) except: print("发生错误") # 3、返回的是一个Response类型的数据,需要转化为bytes类型 html = rsp.read() # 4、把bytes类型的数据放入lxml的etree中,方便用xpath解析 tree = etree.HTML(html) # 5、用xpath解析html aList = tree.xpath('//div[@class = "img"]/a') ''' aList = tree.xpath('//div[@class = "img"]/a') 此代码的意思是:首先找到一个有class属性,并且属性值为img 的div标签,再获得该标签下的a标签 ''' # 6 、获得a标签下的img标签的alt属性和src属性,同样用xpath for a in aList: name = str(a.xpath('./img/@alt')) imgUrl = str(a.xpath('./img/@src')) ''' 此时获得的name和imgUrl并不是标准的格式,而是 ['*****************']这样的,所以需要用字符串截取 ''' name = name[2:-2] imgUrl = imgUrl[2:-2] ''' 该网站的图片标准链接是以http开头的,而获取的imgUrl有的缺失了 一部分,所以加一个判断,如果没有,就加上 ''' t = imgUrl[:4] if t == "http": imgUrl = imgUrl else: imgUrl = "http://www.xiaohuar.com" + imgUrl # 通过nema 和 imgUrl下载图片 getIMg(name, imgUrl) return None if __name__ == '__main__': pageUrls = getPageUrl() for pageUrl in pageUrls: getImg(pageUrl)