妹子图爬虫第一弹

本教程是根据 小白爬虫第一弹之抓取妹子图 编写

首先上边卧槽哥写的这个爬虫教程看过好几遍了,自己也跟着写了两三次了。开始觉得 哈,这么厉害,python 爬虫原来这么简单,因垂丝汀。但是后来发现“自己跟着写过”这个过程,其实能记住的知识很少。加上最近自己一直很迷茫,不知道该往哪个方面发展,不知道该学什么,在 python 和 java 中纠结,在 爬虫 还是 服务器 中纠结。前两周还看了两周的 用Python和Pygame写游戏,慢慢学着发现,教程是基于 python2 的,而我的电脑安装的环境是 python3.5 的,很多教程上需要的包 和一些方法都不能用,而且教程已经是六年前的了,不能说已经被放弃了吧,还是有些过时,python 执行效率又不高,只能写一些小游戏。所以说还是从基础开始,往深里学,用心学习。

想起了之前看到的一张图

自己听过的不如读过的,读过的不如讨论过的,讨论过的不如教给其他人的。所以我决定以后要把自己学过的知识,自己写出来,写在博客里。这样自己也印象比较深刻,要是我写的博文能帮到其他人那就更好了。

基础环境

首先,我承认,我看上面所说的那个教程的时候,完全是被要爬取的网站吸引了。毕竟xx是学习第一动力(/滑稽)。

下面先来看看完成这篇教程所需要的基础环境

  • Python。本教程是基于 python3 来写。windows用户可以安装 anaconda,这是一个Python的科学计算发行版本,作者打包好多好多的包。
  • Requests。网络请求包。
  • beautifulsoup。可以从 html 文件中提取数据,非常方便,不用再搞那些恶心的正则表达式了。
  • LXML。一个HTML解析包 用于辅助beautifulsoup解析网页。

安装这些模块的话可以通过命令行来安装

1
2
3
4
5
6
7
conda install requests
conda install beautifulsoup4
conda install lxml
或者
pip install requests
pip install beautifulsoup4
pip install lxml

代码

重点来了!!我们要爬的网站是 妹子图 , 开不开心,激不激动。

网站的 http://www.mzitu.com/all 页面有整个网站全部的数据,贼良心。我们就在这个页面开启我们的爬虫之旅。Just do it!

1
2
3
4
5
6
7
8
9
10
11
import requests
import os
from bs4 import BeautifulSoup

headers = {'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"} ## 浏览器请求头

all_url = 'http://www.mzitu.com/all'

start_html = requests.get(all_url, headers=headers)##使用 requests 来获取 all_url 的内容,并且把 headers 作为请求头

print(start_html.text) ##把爬取到的内容打印出来 !!!记住网页内容是 .text

执行上面的代码会在控制台输出 all_url 页面的 html 源码。

目前只是爬到了网页的 html 源文件,但是我们是要爬图的啊!!!我们要美女图啊!!!爬虫才刚开始,慢慢来。

在 chrome 中打开 http://www.mzitu.com/all,按下 F12 调出开发者调试工具。

如图:

点击调试窗口左上角的那个小箭头,这样浏览器会根据你鼠标选中的视图显示相应的 html 代码。

如图,所有的图片链接地址都在 <li>...</li>

随便点开一个 <li> 标签

会发现图片页面的地址在<a>标签的href属性中、主题在<a>标签中。所以我们只要爬取所有<li>标签里的内容就能爬取我们想要的地址了。

但是页面里还有好多不符合要求的<li>标签,所以要筛选一下。通过观察发现,所有的文章主题地址都在 <div class='all'>...</div> 标签里。就是 <div class='all'> 里的 <a>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests
from bs4 import BeautifulSoup

headers = {'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"} ## 浏览器请求头

all_url = 'http://www.mzitu.com/all'

start_html = requests.get(all_url, headers=headers)##使用 requests 来获取 all_url 的内容,并且把 headers 作为请求头

all_soup = BeutifulSoup(start_html.text,'lxml') ##使用BeautifulSoup来解析我们获取到的网页(‘lxml’是指定的解析器 具体请参考官方文档哦)

all_a = Soup.find('div', class_='all').find_all('a') ##意思是先查找 class为 all 的div标签,然后查找所有的<a>标签。
for a in all_a:
print(a)

运行结果如下:

然后就该提取我们想要的内容了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests
from bs4 import BeautifulSoup

headers = {'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"} ## 浏览器请求头

all_url = 'http://www.mzitu.com/all'

start_html = requests.get(all_url, headers=headers)##使用 requests 来获取 all_url 的内容,并且把 headers 作为请求头

all_soup = BeutifulSoup(start_html.text,'lxml') ##使用BeautifulSoup来解析我们获取到的网页(‘lxml’是指定的解析器 具体请参考官方文档哦)

all_a = Soup.find('div', class_='all').find_all('a') ##意思是先查找 class为 all 的div标签,然后查找所有的<a>标签。
for a in all_a:
title = a.get_text()
href = a['href]

结果:

然后我们在随便打开一个上面打印出来的链接地址,会发现页面中只有一张图啊,点击 下一页 会发现 url 一直在变,就是在第一张图的 url 后跟 ‘/‘ + 数字,就代表第几张图。所以只需拿到最后一张图的页码,然后访问第一张图到最后一张图所有的url就可以爬到全部的图了。

观察发现页码栏都在<div class='pagenavi'> 标签下,而最后一页的页码是 标签中倒数第二个 <span> 中的内容,所以这一波操作来了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import requests
from bs4 import BeautifulSoup

headers = {'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"} ## 浏览器请求头

all_url = 'http://www.mzitu.com/all'

start_html = requests.get(all_url, headers=headers)##使用 requests 来获取 all_url 的内容,并且把 headers 作为请求头

all_soup = BeutifulSoup(start_html.text,'lxml') ##使用BeautifulSoup来解析我们获取到的网页(‘lxml’是指定的解析器 具体请参考官方文档哦)

all_a = Soup.find('div', class_='all').find_all('a') ##意思是先查找 class 为 all 的div标签,然后查找所有的<a>标签。
for a in all_a:
title = a.get_text()
href = a['href]
html = requests.get(href,headers=headers)
html_soup = BeautifulSoup(html.text,'lxml)
max_span = html_soup.find('div',class_='pagenavi').find_all('span')[-2].get_text()##[-2]代表倒数第二个
for page in range(1, int(max_span)+1):
page_url = href + '/' + str(page)
print(page_url)

这时我们就得到了每张图所在的链接地址,距离爬到我们心心念念的图片地址还有最后一步。发现我们需要的地址在 <div class=”main-image”> 中的 <img> 标签的 src 属性中。

继续操作一波

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests
from bs4 import BeautifulSoup

headers = {'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"} ## 浏览器请求头

all_url = 'http://www.mzitu.com/all'

start_html = requests.get(all_url, headers=headers)##使用 requests 来获取 all_url 的内容,并且把 headers 作为请求头

all_soup = BeutifulSoup(start_html.text,'lxml') ##使用BeautifulSoup来解析我们获取到的网页(‘lxml’是指定的解析器 具体请参考官方文档哦)

all_a = Soup.find('div', class_='all').find_all('a') ##意思是先查找 class 为 all 的div标签,然后查找所有的<a>标签。
for a in all_a:
title = a.get_text()
href = a['href]
html = requests.get(href,headers=headers)
html_soup = BeautifulSoup(html.text,'lxml)
max_span = html_soup.find('div',class_='pagenavi').find_all('span')[-2].get_text()##[-2]代表倒数第二个
for page in range(1, int(max_span)+1):
page_url = href + '/' + str(page)
page_html = requests.get(page_url,headers=headers)
page_soup = BeautifulSoup(page_html.text, 'lxml')
img_url = page_soup.find('div', class_='main-image').find('img')['src']
print(img_url)

hahahah,完美,这不就是我们想要的嘛。但是还要继续操作,我们只拿到了图片的 url ,还要把这些图片下载到本地才算“爬虫”啊。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import requests ##导入requests
from bs4 import BeautifulSoup ##导入bs4中的BeautifulSoup
import os


headers = {'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"}##浏览器请求头(大部分网站没有这个请求头会报错、请务必加上哦)
all_url = 'http://www.mzitu.com/all' ##开始的URL地址
start_html = requests.get(all_url, headers=headers) ##使用requests中的get方法来获取all_url(就是:http://www.mzitu.com/all这个地址)的内容 headers为上面设置的请求头、请务必参考requests官方文档解释
Soup = BeautifulSoup(start_html.text, 'lxml') ##使用BeautifulSoup来解析我们获取到的网页(‘lxml’是指定的解析器 具体请参考官方文档哦)
all_a = Soup.find('div', class_='all').find_all('a') ##意思是先查找 class为 all 的div标签,然后查找所有的<a>标签。
for a in all_a:
title = a.get_text() #取出a标签的文本
path = str(title).strip() ##去掉空格
os.makedirs(os.path.join("D:\mzitu", path)) ##创建一个存放套图的文件夹
os.chdir("D:\mzitu\\"+path) ##切换到上面创建的文件夹
href = a['href'] #取出a标签的href 属性
html = requests.get(href, headers=headers) ##上面说过了
html_Soup = BeautifulSoup(html.text, 'lxml') ##上面说过了
max_span = html_Soup.find('div', class_='pagenavi').find_all('span')[-2].get_text() ##查找所有的<span>标签获取第十个的<span>标签中的文本也就是最后一个页面了。
for page in range(1, int(max_span)+1): ##不知道为什么这么用的小哥儿去看看基础教程吧
page_url = href + '/' + str(page) ##同上
img_html = requests.get(page_url, headers=headers)
img_Soup = BeautifulSoup(img_html.text, 'lxml')
img_url = img_Soup.find('div', class_='main-image').find('img')['src'] ##这三行上面都说过啦不解释了哦
name = img_url[-9:-4] ##取URL 倒数第四至第九位 做图片的名字
img = requests.get(img_url, headers=headers)
f = open(name+'.jpg', 'ab')##写入多媒体文件必须要 b 这个参数!!必须要!!
f.write(img.content) ##多媒体文件要是用conctent哦!
f.close()

然后进行进一步的封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import requests
from bs4 import BeautifulSoup
import os

class mzitu():

def all_url(self, url):
html = self.request(url)##调用request函数把套图地址传进去会返回给我们一个response
all_a = BeautifulSoup(html.text, 'lxml').find('div', class_='all').find_all('a')
for a in all_a:
title = a.get_text()
print(u'开始保存:', title) ##加点提示不然太枯燥了
path = str(title).replace("?", '_') ##我注意到有个标题带有 ? 这个符号Windows系统是不能创建文件夹的所以要替换掉
self.mkdir(path) ##调用mkdir函数创建文件夹!这儿path代表的是标题title哦!!!!!不要糊涂了哦!
href = a['href']
self.html(href) ##调用html函数把href参数传递过去!href是啥还记的吧? 就是套图的地址哦!!不要迷糊了哦!

def html(self, href): ##这个函数是处理套图地址获得图片的页面地址
html = self.request(href)
max_span = BeautifulSoup(html.text, 'lxml').find('div', class='pagenavi').find_all('span')[-2].get_text()
for page in range(1, int(max_span) + 1):
page_url = href + '/' + str(page)
self.img(page_url) ##调用img函数

def img(self, page_url): ##这个函数处理图片页面地址获得图片的实际地址
img_html = self.request(page_url)
img_url = BeautifulSoup(img_html.text, 'lxml').find('div', class_='main-image').find('img')['src']
self.save(img_url)

def save(self, img_url): ##这个函数保存图片
name = img_url[-9:-4]
img = self.request(img_url)
f = open(name + '.jpg', 'ab')
f.write(img.content)
f.close()

def mkdir(self, path): ##这个函数创建文件夹
path = path.strip()
isExists = os.path.exists(os.path.join("D:\mzitu", path))
if not isExists:
print(u'建了一个名字叫做', path, u'的文件夹!')
os.makedirs(os.path.join("D:\mzitu", path))
os.chdir(os.path.join("D:\mzitu", path)) ##切换到目录
return True
else:
print(u'名字叫做', path, u'的文件夹已经存在了!')
return False

def request(self, url): ##这个函数获取网页的response 然后返回
headers = {'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"}
content = requests.get(url, headers=headers)
return content

Mzitu = mzitu() ##实例化
Mzitu.all_url('http://www.mzitu.com/all') ##给函数all_url传入参数 你可以当作启动爬虫(就是入口)

大功告成!

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×

keyboard_arrow_up 回到顶端