tsvico的博客

好的代码像粥一样,都是用时间熬出来的

python爬虫入门到进阶(六)

本篇

妹子图另一种爬取方式
最新表情包爬取

妹子图爬取

相同的操作:

第一步,打开浏览器,在地址栏输入我们的目标网址

第二步,打开控制台查看源码

第三步,尝试分析源码相同元素的规律

第四步,写代码解析目标文件

这节开始还是要说一下妹子图的抓取(这里没有用多线程)

良心站长,以外的发现妹子图站点有一个综合页面,非常适合抓取(源码规律性强)

image

和上一篇相似,我们将鼠标放在第一个超链接上,右键检查,就可以看到该链接指向的地址

image

点击后发现,和上一个保存妹子图的页面相似,由于能直接找到链接,这里就可以简化很多步骤

先把要用到的包调用一下

1
2
3
4
5
6
7
#encoding: utf-8
import urllib2
from bs4 import BeautifulSoup
import os
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

为了简化代码,也让代码更美观,我们把网页请求写在了一个模块中

1
2
3
4
5
6
7
8
def request(url):
heades = {
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36',
'Referer':'http://www.mzitu.com',
}
req = urllib2.Request(url,headers=heades)
html = urllib2.urlopen(req)
return html

下载图片也可以单独写一下,注释里写的很详细

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#下载图片
def download(max_span):
for page in range(1,int(max_span)+1): #如果list空了只要十页图片
page_url = href + '/' +str(page) #专辑编号加上页码
print(page_url) #图片页面地址 会报错

img_html = request(page_url)

img_soup = BeautifulSoup(img_html,"lxml")
#img_url = img_soup.find('div',class_='main-image').find('img')['src']
img_url = img_soup.find('img',alt = title)
if img_url is None:
continue
else:
img_url = img_url['src']
##print(img_url)
name = img_url[-9:-4]##取URL 倒数第四至第九位 做图片的名字
img = request(img_url)
f = open(name+'.jpg','ab')#写入多媒体文件必须要b这个参数
f.write(img.read())
f.close()

设置图片保存目录

1
path = ""

入口URL

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

调用一下上边定义的模块

1
start_html = request(all_url)

这里可以打印一下看看是否成功获取,如果获取成功,那就成功一半了

1
print(start_html.read())

使用BeautifulSoup来解析我们获取到的网页,‘lxml’是指定的解析器

1
soup = BeautifulSoup(start_html,"lxml")

解析a标签

1
all_a = soup.find('div',class_ ='all').find_all('a')

得到a标签,也就有了子页面的入口了

image

我们需要访问这个页面,提取这个页面中的图片

但是这样我们只能得到每个页面中的一张图片

仔细观察发现

image

我们找到了上一篇用到的span标签,提取这个循环访问就可以每张都下载下来

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
for a in all_a:
title = a.get_text() ##取出a标签的文本
if (title!=''):
print ("爬取"+title)
if(os.path.exists(path+title.strip().replace('?',''))):
print "目录已存在"
else:
os.makedirs(path+title.strip().replace('?','')) ##创建存放文件夹
os.chdir(path + title.strip().replace('?','')) ##切换到上述文件夹


href = a['href'] ##取出a标签的href属性
# #print(title)
print(href)
if href.find("old") != -1:
continue

html = request(href)
html_soup = BeautifulSoup(html,"lxml")
list = html_soup.find_all('span')

#关键,不判断容易报错停止
if len(list):
max_span = html_soup.find_all('span')[10].get_text()##取出所有<span>标签,获取第十个中文本,就是最好一个页面
else:
max_span='10'
print(max_span)
#for page in range(1,int(max_span)+1):
download(max_span)

最新表情包

image

经过多次寻找规律,会发现

image

image

image

有木有找到?

导入包

1
2
3
4
5
#encoding: utf-8
import requests
import threading
import urllib
from bs4 import BeautifulSoup

这次上一个有些不同,因为这一个页面规律太明显,我们提前创建了一个集合

1
2
3
4
5
6
PAGE_URL_LIST = []
#表情包链接列表
BESE_PAGE_URL = "https://www.doutula.com/photo/list/?page="
for x in range(1,1500):
url = BESE_PAGE_URL + str(x)
PAGE_URL_LIST.append(url)

上边的循环次数要保证比下图中的最大页码小,不然程序运行到最后会崩溃

image

之后的代码很简单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
for page_url in PAGE_URL_LIST:
#url请求
response = requests.get(page_url)
#使用返回的数据构建besu对象

#requests对象中 response.content返回的是二进制的数值,
# response.text返回的是Unicode型的数据
# 也就是说,如果你想获取文本,可以通过.text
# 如果你想获取图片,文件可以通过 .content
soup = BeautifulSoup(response.content,'lxml')
#获取所有的标签
img_list = soup.find('div',class_ = 'page-content').find_all('img',class_ = 'img-responsive lazy image_dta')
for img in img_list:
title = img['alt']
src = img['data-original']
print(title)
print(src)
#获取图片名称
filename = title
#拼接路径下载
#path = os.path.join("image2",filename)
z = src[-4:] #后缀取名
path = 'images2'+ '/' +title.strip().replace('?','')+z
urllib.urlretrieve(src,path)

。。。会不会太快了、、、

多线程抓取留到下一节

坚持原创技术分享,您的支持将鼓励我继续创作!