本教程是根据 小白爬虫第一弹之抓取妹子图 编写
杂 首先上边卧槽哥写的这个爬虫教程看过好几遍了,自己也跟着写了两三次了。开始觉得 哈,这么厉害,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 requestsimport osfrom bs4 import BeautifulSoupheaders = {'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) print(start_html.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 requestsfrom bs4 import BeautifulSoupheaders = {'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) all_soup = BeutifulSoup(start_html.text,'lxml' ) all_a = Soup.find('div' , class_='all' ).find_all('a' ) for a in all_a: print(a)
运行结果如下:
然后就该提取我们想要的内容了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import requestsfrom bs4 import BeautifulSoupheaders = {'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) all_soup = BeutifulSoup(start_html.text,'lxml' ) all_a = Soup.find('div' , class_='all' ).find_all('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 requestsfrom bs4 import BeautifulSoupheaders = {'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) all_soup = BeutifulSoup(start_html.text,'lxml' ) all_a = Soup.find('div' , class_='all' ).find_all('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() 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 requestsfrom bs4 import BeautifulSoupheaders = {'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) all_soup = BeutifulSoup(start_html.text,'lxml' ) all_a = Soup.find('div' , class_='all' ).find_all('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() 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 from bs4 import BeautifulSoup import osheaders = {'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) Soup = BeautifulSoup(start_html.text, 'lxml' ) all_a = Soup.find('div' , class_='all' ).find_all('a' ) for a in all_a: title = a.get_text() path = str(title).strip() os.makedirs(os.path.join("D:\mzitu" , path)) os.chdir("D:\mzitu\\" +path) 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() 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 ] img = requests.get(img_url, headers=headers) f = open(name+'.jpg' , 'ab' ) f.write(img.content) 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 requestsfrom bs4 import BeautifulSoupimport osclass mzitu () : def all_url (self, url) : html = self.request(url) 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("?" , '_' ) self.mkdir(path) href = a['href' ] self.html(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) 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) : 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' )
大功告成!