第56讲:一只爬虫的自我修养4——OOXX
一 妹子图网站的一些规律:
1 图片的url地址(jandan.net/ooxx/page-1290#comments)除了页码数会变,其它地方是不会改变的
2 获取最新页面的办法:
在刚开始进入该服务器的文件夹ooxx的时候(jandan.net/ooxx),url后面是没有链接页面的;
通过google浏览器自带的审查元素(检查)选项,可看到该网页的源代码;
这样我们可以知道,最新页面的地址保存在span标签里面的,有一个class属性对应的值为:“current-comment-page”;
因此,我们可以通过搜索“current-comment-page”这一属性值后,偏移三位得到最新页面的页码数(我们是不可以输入具体的数字的,该数字会一直变,所以需要自动获取)
3 图片的地址都来自新浪服务器,且该地址保存在img标签里面的src属性内。
二 具体代码
1 import urllib.request 2 import os # 用来创建文件夹 3 import random 4 5 # 打开链接对应的网页,读取该网页的内容 6 def url_open(url): 7 req = urllib.request.Request(url) # 创建Request对象 8 # 添加请求头模拟浏览器访问 9 req.add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36') # 添加请求头模拟浏览器访问 10 11 """ 12 使用代理 13 proxies = ['119.6.144.70:81','111.1.36.9:80','203.144.144.162:8000'] 14 proxy = random.choice(proxies) 15 16 procy_support = urllib.request.ProxyHandler({'http':proxy}) 17 opener = urllib.request.build_opener(proxy_support) 18 urllib.request.install_opener(opener) 19 20 问题:为什么使用代理会出现莫名奇妙的图片? 21 """ 22 23 24 response = urllib.request.urlopen(req) # 开始访问该网页并将网页内容保存在response变量中 25 html = response.read() 26 27 return html 28 29 30 # 将获取到的网页信息解码,找到要爬取的内容并将其返回给主函数 31 def get_page(url): 32 html = url_open(url).decode('utf-8') # 将网页内容解码为utf-8格式 33 34 a = html.find('current-comment-page') + 23 # 在网页中查找当前图片地址,偏移23(current-comment-page的字符个数)到1293的1的位置 35 b = html.find(']',a) # 从a开始找到第一个方括号返回它的索引坐标 36 37 return html[a:b] 38 39 # 查找要爬取的页面的图片的地址,并将它保存在一个列表中 40 def find_imgs(url): 41 html = url_open(url).decode('utf-8') # 将网页内容解码为utf-8格式 42 img_addrs = [] 43 44 a = html.find('img src=') # 起始地址,find表示字符串的方法,在字符串中查找该元素 45 while a != -1: # 找不到img标签的时候,程序会返回-1 46 b = html.find('.jpg',a,a+255) 47 if b != -1: # b != -1表示找到图片地址了 48 img_addrs.append(html[a+9:b+4]) # a+9就是索引到http的h,b+4就是加上.jpg的长度 49 else: 50 b = a + 9 # 为了让程序查找下一个图片地址标识:img src=,9表示该字符串的长度 51 a = html.find('img src=',b) # 每一次a都会进行下一次寻找,下一次寻找的启示位置就是上一次的结束位置 52 53 return img_addrs 54 55 56 # 将爬取到的内容保存在某个文件中 57 def save_imgs(folder,img_addrs): 58 for each in img_addrs: 59 filename = each.split('/')[-1] # 按反斜杠分割每个地址字符串后得到一个列表,通过索引值-1取该列表的最后一个元素即为图片名称 60 with open(filename,'wb') as f: 61 img = url_open(each) # 打开对应的图片,并保存在变量img中 62 f.write(img) # 打开的图片写入(保存在)filename文件夹中 63 64 65 def class56_download_mm(folder = 'OOXX',pages = 10): # folder表示文件名,pages表示要爬取的页数 66 os.mkdir(folder) # 创建文件夹 67 os.chdir(folder) # 更改目录 68 69 url = "https://jandan.net/ooxx/" # 要爬取的网页地址 70 page_num = int(get_page(url)) # 获取该网站某一页的地址并把它赋值给变量page_num 71 72 for i in range(pages): # 获取从当前页开始后共pages页对应网站的地址 73 page_num -= i # 第一张图片是1293,第二张图片是1292, 74 page_url = url + 'page-' + str(page_num) + '#comments' # 构造该网页的地址并保存 75 img_addrs = find_imgs(page_url) # 找到该页面中所有图片的地址,并将它保存在一个列表中,该列表是find——imgs()函数的返回值 76 save_imgs(folder,img_addrs) # 将所有图片都保存在指定文件夹中 77 78 if __name__ == '__main__': # if __name__ == '__main__'的意思是:当.py文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行; 79 # 当.py文件以模块形式被导入时,if __name__ == '__main__'之下的代码块不被运行。 80 class56_download_mm()