基本原理
我们爬取图片的最终目的是将每一个用户的id作为一个key,对应每个用户下都是一个人的照片,再将此数据集作为训练集输入模型,来提高模型的精度。所以第一步就是要获取尽量多的用户id,从而来追踪该id的相册里的图片。要得到足够多的id,我们利用人人网找人的搜索框功能通过关键词学校和年份来获得用户Id,所以首先我们需要两个list,一个是学校的list,另一个是年份的lIst。
一、建立学校和年份列表
school.list是提前准备好的从网上找的中国高校的名称,将其读取到school.list中:
school_list = []
file_school = open("C:/Users/liuzhifeng/Desktop/人人网爬虫项目/school.list", 'r', encoding="utf-8")
line = file_school.readline()
while line:
line = line.strip()
school_list.append(line)
line = file_school.readline()
file_school.close()
将年份范围设定在1980——2016:
year_list = []
for i in range(1980, 2017):
year_list.append(str(i))
建立一个list和dict来存放爬取的所有id,由于之前已经爬取了一部分避免重复,先把之前的读取出来:
all_dict = {}
all_list = []
file_all = open("./all", 'r', encoding="utf-8")
line = file_all.readline()
while line:
line = line.strip()
all_dict[line] = "1"
all_list.append(line)
line = file_all.readline()
file_all.close()
print(f"len(all_dict)={len(all_dict)}")
print(f"len(all_list)={len(all_list)}")
二、模拟登陆
用session发送post请求,cookie保存在其中,维持对话,之后可以持续访问,post_data为用邮箱注册的用户名和密码,关于代理网上有很多免费的和付费的。
proxy = {
'*****',
'*****'
}
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36"
}
session = requests.session()
post_url = "http://www.renren.com/PLogin.do"
post_data = {"email": "***", "password": "***"}
session.post(post_url, data=post_data, proxies=proxy, headers=headers)
三、按条件搜索
利用人人网找人的搜索功能,输入年份和学校,点击跳转,按F12切换到浏览器的network找到跳转时的request url,分析这个url里的变量,除了年份和学校外,还有其他几个改变的参数。根据这个URL获取到的静态页面是一系列用户,再通过正则匹配去找到每个用户的Id。
for n in range(len(school_list)):
for m in range(len(year_list)):
random_num = random.randrange(0, len(all_list))
rand_user = all_list[random_num]
rand_id = random.randrange(1000, 1300)
print(f"rand_user={rand_user}")
print(f"rand_id={rand_id}")
count = 0
while 1:
# 其中count代表翻页
url = 'http://browse.renren.com/sAjax.do?ref_search=&q=&p=%5B%7B%22t%22%3A%22univ%22%2C%22' \
'name%22%3A%22{0}%22%2C%22id%22%3A%22{2}%22%2C%22year%22%3A%22{1}%22%7D%5D&s=0&u={3}&act=search' \
'&offset={4}&sort=0'.format(school_list[n], year_list[m], rand_id, rand_user, count)
try:
r = session.get(url, timeout=2, proxies=proxy, headers=headers)
except Exception as e:
print(e)
continue
# 请注意修改保存的日期名
file_path = './20191106'
with open(file_path, "a+") as f:
f_all = open("./all", "a+")
x = re.findall('<strong>.*id=(\d+)', str(r.text))
for i in range(len(x)):
if all_dict.__contains__(x[i]):
print(f"exists: {school_list[n]} {year_list[m]} {x[i]}")
else:
album_url = 'http://photo.renren.com/photo/{0}/albumlist/v7'.format(x[i])
album_web = session.get(album_url, timeout=2, proxies=proxy, headers=headers)
album_find = re.findall('"albumId":"(.*?)"', str(album_web.text))
if len(album_find) == 1:
# 判断是否有相册以及相册中是否有照片
photo_url = 'http://photo.renren.com/photo/{0}/album-{1}/v7'.format(x[i],album_find[0])
photo_web = session.get(photo_url, timeout=2, proxies=proxy, headers=headers)
if re.findall('photo-list-main', str(photo_web.text)):
#如果既有相册,且相册中不为空,泽写入文件中
f.write(x[i]+'\n')
f_all.write(x[i]+'\n')
all_dict[x[i]] = "1"
print(f"add: {school_list[n]} {year_list[m]} {x[i]}")
else:
continue
else:
continue
f_all.close()
f.close()
print(count)
count += 10
if count % 500 == 0:
count = 0
break
print(m)
print(n)
可能存在用户没有相册或相册为空的情况,将其排除避免后续出现空文件夹,将新获得的id存到lst中,要注意去重。