作业思路
在这次作业爬取的是新浪微博的用户信息,日爬取量25000个用户,寄存在云服务器上运行(不过服务器每次都因为内存不够把进程给杀了,汗...)
作业选取的网址是新浪微博手机版网页,主要思路就是解析json数据,不过函数之间的逻辑有点绕,也就是爬取用户的粉丝的粉丝,重复进行,不过没有加入去重函数和结束函数,思路看图:
作业逻辑
还有一个点需要注意的是如何使cookies保持长时间的有效,这是这个脚本的一个关键点,所以在这里选择了requests里的session这个方法,可以更新请求的头,而cookies就是在请求的头里,经过验证,在爬取的过程中没有遇到失效的情况,倒是请求过快以及多次启动脚本容易产生请求403的结果,也就是IP被封。更具体的解释在代码的注释里有。
作业结果
图一
图二
作业代码
# -*- coding: utf-8 -*-
import requests
import json
import re
import time
import MySQLdb
# 这个是爬取一个用户的粉丝的100个ID
def start_url(url):
s = requests.Session()
r = s.get(url, headers=headers)
totaldata = json.loads(r.text)
totalurl = []
# 这个是单页里的粉丝的一层信息
for i in totaldata["cards"][0]["card_group"]:
item = {}
item["nickname"] = i["user"]["screen_name"]
item["id"] = i["user"]["id"]
item["fans"] = i["user"]["followers_count"]
item["follows"] = i["user"]["follow_count"]
item["url"] = i["user"]["profile_url"]
print "正在处理: " + str(i["user"]["id"])
time.sleep(2)
user_data(item)
totalurl.append(item["id"])
s.headers.update(headers)
for one in totalurl:
change_url(one)
#这个函数是生成新的用户的URL,所以应该是返回上一个函数,这样可以解析指数增长的用户
#这里是生成了10页用户的URL,再将这10页URL传到上一个函数里,提取每一页里的10个粉丝的信息
#这里所要保证的是传入的每一个ID都是不同的,输出来的是每一个ID所对应的每一页的URL
def change_url(page):
baseurl = "https://m.weibo.cn/api/container/getIndex?containerid=231051_-_fans_-_%s&luicode=10000011&lfid=1005053846717719&featurecode=20000180" %page
for one in range(1,11):
try:
url = baseurl + "&page={}".format(one)
time.sleep(2)
start_url(url)
except:
continue
#这个函数用来获取用户的更具体的信息,需要接受上面的生成器,一方面生成ID,一方面是接收一些信息来传递到存库函数中保存起来。
def user_data(user_id):
one_url = "http://m.weibo.cn/api/container/getIndex?containerid=230283%s_-_INFO" %user_id["id"]
two_url = "&title=%s" %user_id["nickname"]
three_url = "&luicode=10000011&lfid=230283%s&featurecode=20000180" %user_id["id"]
url = one_url + two_url + three_url
s = requests.Session()
r = s.get(url, headers=headers)
totaldata = json.loads(r.text)
i = totaldata["cards"][0]["card_group"]
data = {}
data["nickname"] = user_id["nickname"]
try:
data["biaoqian"] = i[3]["item_content"]
except:
data["biaoqian"] = "空"
try:
data["sex"] = i[1]["item_content"]
except:
data["sex"] = "未知"
try:
data["place"] = i[2]["item_content"]
except:
data["place"] = "未知"
data["lv"] = totaldata["cards"][1]["card_group"][0]["item_content"] #等级
try:
data["res_time"] = totaldata["cards"][1]["card_group"][2]["item_content"] #注册时间
except:
data["res_time"] = "空"
data["id"] = user_id["id"]
data["fans"] = user_id["fans"]
data["follows"] = user_id["follows"]
data["url"] = user_id["url"]
print time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
insert(data)
def mysql_conn():
conn=MySQLdb.connect(
host='127.0.0.1',
user = "root",
passwd = "882645",
charset = "utf8",
db='Lagou',
port = 3306
)
return conn
#建表
def create_table():
create_sql='''
CREATE TABLE `weibos`(
LIST INT(11) NOT NULL AUTO_INCREMENT,
nickname VARCHAR(255),
biaoqian VARCHAR(255),
sex VARCHAR(255),
place VARCHAR(255),
id VARCHAR(255),
fans VARCHAR(255),
follows VARCHAR(255),
lv VARCHAR(255),
res_time VARCHAR(255),
url VARCHAR(255),
PRIMARY KEY (`LIST`)
)ENGINE=INNODB DEFAULT CHARSET =utf8
'''
conn=mysql_conn()
with conn:
cursor = conn.cursor()
cursor.execute(create_sql)
conn.commit()
#插入记录
def insert(it):
sql='insert into weibos (nickname,biaoqian,sex,place,id,fans,follows,lv,res_time,url) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'
conn = mysql_conn()
with conn:
cursor = conn.cursor()
try:
cursor.execute(sql,(it['nickname'],it['biaoqian'],it['sex'],it['place'],it['id'],it['fans'], it['follows'],it["lv"],it["res_time"],it['url']))
cursor.connection.commit()
except BaseException as e:
print u"错误在这里>>>>", e, u"<<<<错误在这里"
conn.commit()
if __name__ == '__main__':
headers = { "Connection":"keep-alive",
"Accept":"application/json, text/plain, */*",
"X-Requested-With":"XMLHttpRequest",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36",
"DNT":"1",
"Accept-Encoding":"gzip, deflate, sdch",
"Accept-Language":"zh-CN,zh;q=0.8",
"Cookie":"_T_WM=10f51ed94c4f4324c8adfaeeaf3b6c7a; ALF=1496672460; SCF=Asenm4RgczizSoBCdtR_GtVS4yjQ0rI-fnnSnq1Z5h60mMnfCGjbxHYIsFwmxprk8h9DOikPiXPXiPKHXPyqVPQ.; SUB=_2A250CsRrDeRhGeNJ7VsZ8i_PyTiIHXVX9OwjrDV6PUNbktBeLWPgkW0aj2ty_KahcQEYR7pWKwQDBQsJCg..; SUBP=0033WrSXqPxfM725Ws9jqgMF55529P9D9W5VPg2H0mI-Z6NLOPLMSPkK5JpX5KMhUgL.Fo-NSo.Reo20eoB2dJLoI7DhqPi79gyyMGW4; SUHB=0k1CYdpYNb60Hz; SSOLoginState=1494135867; H5_INDEX=0_all; H5_INDEX_TITLE=Carpehappy; M_WEIBOCN_PARAMS=featurecode%3D20000180%26oid%3D4103787444327240%26luicode%3D10000011%26lfid%3D231051_-_fans_-_2322168320"}
start = "http://m.weibo.cn/api/container/getIndex?containerid=231051_-_fans_-_2322168320&luicode=10000011&lfid=1005052322168320&featurecode=20000180&page=1"
# 创表
create_table()
start_url(start)
# 个人信息页:https://m.weibo.cn/api/container/getIndex?containerid=2302833936433808_-_INFO&title=%25E5%259F%25BA%25E6%259C%25AC%25E4%25BF%25A1%25E6%2581%25AF&luicode=10000011&lfid=2302833936433808&featurecode=20000180
# 粉丝页:https://m.weibo.cn/api/container/getIndex?containerid=231051_-_fans_-_3936433808&luicode=10000011&lfid=1005053936433808&featurecode=20000180&page=2
# 最多只能100多条信息
吐槽一下,为什么我的这个IP打开简书特别慢,几乎是打不开的状态...,无奈换了个IP才登上,为了登个简书也是够拼的。