python妹子爬虫(1)

这篇博客写一个python妹子爬虫(嘿嘿嘿)

我们要爬取的网站是http://www.doyo.cn/tu ,网页是这样的:

1

可以看到,好多美女的。

我们点开其中一个连接,进入其页面,是哇小姐姐真漂亮^^,同时我们发现链接地址地址为http://www.doyo.cn/picture/7399 ,也就是说我们只要知道/picure/后面的数字就可以找到这个小姐姐了!~

2

思路

大体的思路很简单,就是先爬取每一个小姐姐的连接,然后由每个分类爬取这个小姐姐的所有图片。

导入库

1
2
3
4
5
6
7
import random
import time
import requests
from requests.exceptions import RequestException
import json
import os
import re

爬取分类的连接

第一步就是获得分类连接,我们在首页打开Chrome的审查,点开Network选项, 发现在Ajax请求返回了一个Json格式的数据,其中包括了每个小姐姐的信息,其中就有这个小姐姐的网页连接

3

注意到这第七项的7276就是这个小姐姐的连接的后缀了。

这个Ajax的连接是http://www.doyo.cn/tu/getdata?cate=all&tag=all&sort=updatetime&start=50&count=25 ,也就是说我们只要设置其中的start参数就可以无限的得到这些包含小姐姐信息的Json文件连接了。

由此引出第一个函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
data_url = 'http://www.doyo.cn/tu/getdata'
def get_one_page(start):
params = {
"cate": "all",
"tag": "all",
"sort": "updatetime",
"start": start,
"count": 25
}
try:
response = requests.get(url=data_url, params=params)
if response.status_code == 200:
return response.text
return None
except RequestException:
print("NetWork Error")

其中我们传入的参数是start,这里的data_url就是Ajax亲贵根网页。构造一个params字典作为参数然后用requests.get请求网页,我们通过我们传入的params,requests将会自动给我们构建出url连接,如果请求失败,我们设置except,自动抛出”Network Error”

解析Ajax请求返回的Json文本

由上一个函数返回值是一个文本,大概是这个样子的

4

它的本质是一个Json格式的字典,就是前面图片

5

我们定义一个函数,用json解析文档,其中的number是指小姐姐地址的后缀,count是指小姐姐有几张图片,等下我们会用这两个来构建图片的网址:

1
2
3
4
5
6
7
8
9
10
def get_one_data(html):
data = json.loads(html)
if data and 'info' in data.keys():
for info in data.get('info'):
yield {
'title': info[0],
'count': info[1],
'pic': info[6],
'number': info[7]
}

如果data字典中不是None并且字典中有‘info’我们对info中的值进行操作。这个键值我们yield返回一个生成器,生成器每次都会迭代出一个json格式的文本

解析每个json文本,得到链接列表

上一个函数中返回的是一个生成器,每次迭代都会返回json文本,接下来我们就需要根据每每个json文本得到图片的地址了每张小姐姐图片的地址是http://www.doyo.cn/picture/{number}/{index}/viewhttp://www.doyo.cn/picture/{number}/{index}/view ,其中number是小姐姐的编号,index就是某个小姐姐的所有图片中的某一张的编号了我们用一个for语句来得到每张图片。然后yield出所有的地址

1
2
3
4
5
root_url = 'http://www.doyo.cn/picture/{number}/{index}/view'
def get_img_urllist(res):
# root_url = 'http://www.doyo.cn/picture/{number}/{index}/view'
for index in range(1, int(res.get('count')) + 1):
yield root_url.format(number=res.get('number'), index=index)

解析每个链接,得到每一张图片链接

经过上一步得到的图片列表,其中每一个连接的页面将会是这样:

6

用正则表达式匹配图片的链接,先写正则表达式:

1
pattern = re.compile('<img src="(.*?)" id="big_picture" />', re.S)

然后进行匹配:

1
2
3
4
5
6
def get_img_url(imag_url):
print('image_url' , imag_url)
html = get_html(imag_url)
res = re.search(pattern=pattern, string=html)
if res:
return res.group(1)
1
2
3
4
5
6
7
8
9
def get_html(url):
try:
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.text
else:
return None
except RequestException:
print("connection error")

返回链接。

保存图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def save_img(res):
os.chdir(parent_path)
try:
os.mkdir(res.get('title'))
os.chdir(res.get('title'))
except:
pass

url_list = get_img_urllist(res)
for imag_url in url_list:
url = get_img_url(imag_url)
print(imag_url)
try:
filename = str(random.random())
time.sleep(0.1)
response = requests.get(url, headers=headers)
with open(filename + '.jpg', 'wb') as f:
f.write(response.content)
except:
pass

这里我们保存图片时,每个小姐姐都新建一个文件夹存入

main函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

def main(start):
html = get_one_page(start)
res = get_one_data(html)

for each in res:
print(each)
write_to_file(each)
save_img(each)


if __name__ == '__main__':
start = [n * 25 for n in range(0, 1)]
for i in start:
main(i)
j.close()

开始爬取

7

8