我们的爬虫目标是今日头条的美女图片,如下:

我们的任务就是将这些图集保存下来。
首先需要获取到所有的列表,我们在开发者工具中通过浏览器的NetWork可以发现请求的数据包:

分析一下这个数据包:

1
https://www.toutiao.com/search_content/?offset=0&format=json&keyword=%E6%B8%85%E7%BA%AF%E7%BE%8E%E5%A5%B3&autoload=true&count=20&cur_tab=3&from=gallery

通过url我们可以知道几个重要的参数

  • offset 偏移量
  • count 数量
  • cur_tab 当前分类

那么我们每次取一个,然后通过offset自增长的方式挨个取,先访问这个上面的数据包看一下数据结构:

我们需要获取到该图集的链接,即:article_url,进入这篇图集,在NetWork中并没有发现图集有关的请求接口,可能也是混排的,可以查看页面的源码:

真的是混排的写法,我们只需要取出数据即可,提供两种方法,一种就是正则,一种就是自己写一个取文本的函数,这里我用第二种作为演示,下面是取文本的函数:

1
2
3
4
5
6
7
def txt_wrap_by(start_str, end, html):
start = html.find(start_str)
if start >= 0:
start += len(start_str)
end = html.find(end, start)
if end >= 0:
return html[start:end].strip()

我们取出 JSON.parse(“”) 中的数据,观察数据发现:我们取出url就可以了,这里的数据是json但是被转义了,所以就通过正则取出吧:

取到了uri只要在前面拼上http://p3.pstatp.com/然后保存为图片即可~

所有代码:

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
import requests,os,json,re,datetime

# 主函数
def main():
foreach_art_list()

def foreach_art_list():
# 判断目录下是否存在jilv.txt文件 如果存在则读取里面的数值
if os.path.exists('./jilv.txt'):
f = open('./jilv.txt')
n = f.read()
n = int(n)
f.close()
else:
n = 0
while True:
url = 'http://www.toutiao.com/search_content/?offset=' + str(n) + '&format=json&keyword=%E6%B8%85%E7%BA%AF%E7%BE%8E%E5%A5%B3&autoload=true&count=1&cur_tab=3&from=gallery'
re = requests.get(url)
data = re.json()['data']
if not data:
break
# 运行图片下载函数
download_pic(data[0]['article_url'],n)
n = n+1
# 将n写入文件 防止程序运行出错 可以继续运行
with open('./jilv.txt', 'w') as f:
f.write(str(n))

def download_pic(url,n):
download_pic_url = 'http://p3.pstatp.com/'
# 这里必须带上协议头,否则会请求失败
header = {
'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'
}
res = requests.get(url,headers = header)
content = res.text
img_list_json = txt_wrap_by('gallery: JSON.parse("','"),',content)
# 正则获取所有的uri
img_list = re.findall(r'uri\\":\\"(.*?)\\"',img_list_json)
#判断是否有此目录
if 'img' not in os.listdir('.'):
os.mkdir('./img')
if str(n) not in os.listdir('./img'):
os.mkdir('./img/'+str(n))
for v in img_list:
img_path = download_pic_url + v
img_path = img_path.replace("\\", "")
# 读取图片
atlas = requests.get(img_path).content
# 保存图片
with open( './img/' + str(n) + '/' + str(datetime.datetime.now()) +'.jpg', 'wb') as f: # 把图片写入文件内
f.write(atlas)


# 取出两个文本之间的内容
def txt_wrap_by(start_str, end, html):
start = html.find(start_str)
if start >= 0:
start += len(start_str)
end = html.find(end, start)
if end >= 0:
return html[start:end].strip()

# 运行程序
main()

看一下最终效果: