第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()
class56_download_mm.py

 

posted @ 2020-11-03 23:33  洛兰123  阅读(428)  评论(0编辑  收藏  举报