妹子图网站爬虫的修复

妹子图网站爬虫的修复

友情提示:本文内容少儿不宜。

这一次修复的原因是m.mzitu.com 网站的反爬机制又升级了,现在就是直接请求网页也会失败。而之前的程序是模拟浏览器下载图片而没有模拟浏览器请求网页,所以已经不能用了,所以这一次修复的目标是增加模拟浏览器请求、精简代码和制作命令行工具方便图片更新。

如果你想爬图片,推荐爬https://www.mzitu.com/。这个和我爬的https://m.mzitu.com/是一样的,但是更好爬一些。

关于爬取思路的介绍,可以参考这篇博客:m.mzitu.com 网站爬虫的改进

修改后的爬取程序是:

Python
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# 由于Python 升级到 2.7.9 之后引入了一个新特性,当使用urllib.urlopen打开一个 https 链接时,
# 会验证一次 SSL 证书。而当目标网站使用的是自签名的证书时就会抛出此异常。因此需要使用下面的代码
# 全局取消证书验证。
import ssl
import requests
from bs4 import BeautifulSoup
import pandas as pd
import os
import re
ssl._create_default_https_context = ssl._create_unverified_context
headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) " \
"A®ppleWebKit/537.36 (KHTML, like Gecko) " \
"Chrome/66.0.3359.181 Safari/537.36",
"Accept": "image/webp,image/apng,image/*,*/*;q=0.8",
"Referer": "http://m.mzitu.com/138401",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8"}

# 编写一个带请求下载图片的函数,该函数需要两个参数,图片的链接和名字
def download_pic(url, name):
res = requests.get(url, headers = headers)
res.raise_for_status()
playFile = open(name, 'wb')
for chunk in res.iter_content(100000):
playFile.write(chunk)
playFile.close()
# download_pic("https://i.meizitu.net/2018/12/13a01.jpg", "test.jpg")

### 编写一个根据某套妹子图主页链接获取某个妹子的所有图片链接的函数
## 首先编写一个根据某套妹子图主页链接判断该套图的页数的函数
def get_page(url):
session = requests.Session()
req = requests.get(url, headers = headers)
bsObj = BeautifulSoup(req.text, 'html.parser')
page_temp = bsObj.findAll("span", {"class": "prev-next-page"})
for p in page_temp:
page = re.findall(r"1/(.+?)页", p.get_text())
print("该套图一共", page[0], "页")
return int(page[0])

# get_page("https://m.mzitu.com/163028")

### 编写一个函数获取一套图的所有链接
def get_pic_link(url):
link = []
for i in range(1, get_page(url)):
url_temp = url + "/" + str(i)
session = requests.Session()
req = requests.get(url_temp, headers=headers)
bsObj = BeautifulSoup(req.text, 'html.parser')
for j in bsObj.figure.findAll("img"):
link.append(j.attrs["src"])
return link

# get_pic_link("https://m.mzitu.com/163028")

## 获取总页数
def get_total_pages():
url = "https://www.mzitu.com/"
req = requests.get(url, headers = headers)
bsObj = BeautifulSoup(req.text, 'html.parser')
page_temp = bsObj.findAll("a", {"class":"page-numbers"})
return int(page_temp[3].get_text())
# get_total_pages()

## 获取每个妹子的套图链接的函数并输出为一个mzitu.csv文件
def get_all_link():
link = []
name = ['url']
# for i in range(1, 4):
final_page = get_total_pages() + 1
for i in range(1, final_page):
url = "https://m.mzitu.com/page/" + str(i) + "/"
req = requests.get(url, headers = headers)
bsObj = BeautifulSoup(req.text, 'html.parser')
link_list = bsObj.findAll("a", {"href": re.compile("https://m.mzitu.com/[0-9]")})
for m in link_list:
mhref = m.attrs["href"]
if mhref not in link:
link.append(mhref)
print("第"+str(i)+"页完成!")
print("一共%d组图片" % len(link))
test = pd.DataFrame(columns = name, data = link)
test.to_csv("mzitu.csv")
return link

# get_all_link()

### 根据一个套图链接返回其名称
def get_title(url):
req = requests.get(url, headers = headers)
bsObj = BeautifulSoup(req.text, 'html.parser')
title = ""
for i in bsObj.findAll("h2", {"class":"blog-title"}):
title = i.get_text()
return title

# get_title("https://m.mzitu.com/163028")

### 一个根据给定字符串创建字文件夹并设定子文件夹为工作目录的函数
def make_and_cd(foldername):
def mkdir(path):
folder = os.path.exists(path)
if not folder: # 判断是否存在文件夹如果不存在则创建为文件夹
os.makedirs(path) # makedirs 创建文件时如果路径不存在会创建这个路径
print("--- 创建新文件夹... ---")
print("--- 创建完成 ---")
else:
print("--- 文件夹已存在! ---")
mkdir(foldername)
os.chdir(foldername)

## 开始全站爬取
os.chdir("/Users/mr.cheng/Pictures/图片/妹子图/")
make_and_cd("mztu")
cwd = os.getcwd()
all_links = get_all_link()
df = pd.read_csv("mzitu.csv")
all_links = list(df.url)
total_length = len(all_links)
print(total_length)
progress = 0
for i in all_links:
progress += 1
speed = progress / total_length * 100
title = get_title(i)
if not os.path.exists(title):
print("正在下载:", title)
make_and_cd(title)
m = 1
for j in get_pic_link(i):
try:
download_pic(j, name = str(m)+".jpg")
except Exception as e:
print(e)
m += 1
print("下载成功")
os.chdir(cwd)
speed = progress/total_length * 100
print("已完成", speed, "%")

按照上篇博客介绍的方法把其改造成一个命令行工具mztu。以后就可以直接在终端运行mztu更新图片仓库了。

# Python

Comments

Your browser is out-of-date!

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

×