因为最近事情稍微多了些,又正好上第二节课,索性将两次课内容合并在一起(第二节课是被bug强制卡下课的悲惨小欣)/(ㄒoㄒ)/~~
一、基本思路
- 新建文件夹用于存储爬取下来的数据,设置关键词(例如“
眷思量 ”),爬取多页,构造客户代理池,爬取页面存为html文件格式; - 读取关键词命名文件夹下的所有文件,提取html文件中我们需要的具体分析的关键词内容(用户名、发表时间、转赞评数目、内容),存入关键词命名的表格。
二、代码详解
涉及到的库:json 、xlwt 、os 、requests 、urllib.parse 、re ,前三个以前介绍了,见这篇文章数据分析与挖掘常用库,后面三个这里放一下简要介绍:
1. requests
Python第三方库,公认爬取网页最好的库,代码里主要用到requests.get(),其语法为res=requests.get(url,headers=headers,params,timeout) url:要抓取的 url 地址。 headers:用于包装请求头信息。 params:请求时携带的查询字符串参数。 timeout:超时时间,超过时间会抛出异常。
Requests库主要有7个方法,分别是 1.requests.request():构造一个请求,支撑以下各方法的基础方法 2.requests.get():获取HTML网页的主要方法,对应于HTTP的GET 3.requests.head():获取HTML网页头信息的方法,对应于HTTP的HEAD 4.requests.post():向HTML网页提交POST请求的方法,对应于HTTP的POST 5.requests.put():向HTML网页提交PUT请求的方法,对应于HTTP的PUT 6.requests.patch():向HTML网页提交局部修改请求,对应于HTTP的PATCH 7.requests.delete():向HTML页面提交删除请求,对应于HTTP的DELETE
使用 Requests 模块向一个 URL 发起请求后会返回一个 HttpResponse 响应对象,该对象具有以下常用属性。 特殊方法也就是我们代码中用到的json r.json() #Requests中内置的JSON解码器,方便处理json数据 r.raise_for_status() #失败请求(非200响应)抛出异常
2. urllib.parse urlencode()
urllib 是一个收集了多个用到URL的模块的包,urllib.parse 用于解析URL,该模块定义了一个标准接口,用于URL字符串按组件(协议、网络位置、路径等)分解,或将组件组合回URL字符串,并将 “相对URL “转换为给定 “基础URL “的绝对URL,解析内容如下图所示。urlencode() 将字典转换为字符串。
3. re
提供了与 Perl 语言类似的正则表达式匹配操作(Perl借取了C、sed、awk、shell 脚本语言以及很多其他程序语言的特性。其中最重要的特性是它内部集成了正则表达式 的功能,以及巨大的第三方代码库CPAN)。 正则表达式语法规则(我记不住,感觉好难!) 辅助函数(用来检测或显示匹配对象)
def displaymatch(match):
if match is None:
return None
return'<Match: %r, groups=%r>'%(match.group(),match.groups())
基于 re.match() 检查字符串开头,或者 re.search() 检查字符串的任意位置(默认Perl中的行为)。
re.match("c", "abcdef") # No match
re.search("c", "abcdef") # Match
# return <_sre.SRE_Match object; span=(2, 3), match='c'>
4. 数据爬取存入文件夹
base_url = 'http://m.weibo.cn/api/container/getIndex?'
keyword = input('输入关键词')
# 获取当前路径
path = os.getcwd()
print(path)
# 在当前路径下以输入关键词为名创建新文件夹
mkpath = os.path.join(path,keyword)
#获取此py文件路径,在此路径选创建在new_folder文件夹中的test文件夹
if not os.path.exists(mkpath):
os.mkdir(mkpath)
# 提取2-15页内容
for i in range(2,15):
params = {
'containerid':'100103type=1&q={}&t=0'.format(keyword),
'page': i,
'count': 5
}
header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"
}
params = urlencode(params) # (注意param要用urlencode()转换)
url = base_url + params # 将base_url 和params拼接成最终的url
r = requests.get(url=url,headers=header).json()
path_html = os.path.join(mkpath,'{}_{}.html'.format(keyword,i))
# 网页以“关键字_页码.html”命名存储网页文件
with open(path_html,'w',encoding='utf-8') as f:
f.write(json.dumps(r,ensure_ascii=True))
print('Page {} download finish!'.format(i))
输入关键词眷思量 (是的,我就是那个为爱发电、到处给人种草的眷粉,我打算之后对眷眷超话做一次数据分析,啊,不知道能不能被导演姐姐pick?),生成文件夹,打开可以看到 html里面是这样的,乱中有序,我是把它想象成一个鸡蛋,一层套一层,而且类似于字典排布(最近,好像正好在准备《信息简史》第三章讨论,就是关于字典!),我们用[’’][’’]就能方便的读取内容了。
5. 关键词内容存入excel
filename = os.listdir(path)
# 创建6个空列表放
all_screen_name = [] # 创建用户名列表
all_created_at = [] # 创建发布时间列表
reposts_count = [] # 创建转发数列表
comments_count = [] # 创建评论数列表
attitudes_count = [] # 创建点赞数列表
text = [] # 创建微博内容列表
print(filename)
xls = xlwt.Workbook(encoding='utf-8')
sht1 = xls.add_sheet("sheet1",True)
for i in filename:
path_i = path+'/'+i
f = open(path_i,'r',encoding='utf-8')
readfile = f.read()
result = json.loads(readfile,strict=False)
print(result)
items = result['data']['cards']
for item in items:
all_created_at.append(item['mblog']['created_at'])
··· # 其余类似
# 添加表格
# 添加字段
sht1.write(0,0,'num')
sht1.write(0,1,'all_screen_name')
··· # 其余类似
for i in range(1,len(all_screen_name)):
sht1.write(i, 0, i) # 注意是从表格第1行,不是第0行开始排列,同时读取列表是从第0个开始读取
sht1.write(i, 1, all_screen_name[i-1])
··· # 其余类似
xls.save('./法治社会.xls') # 开始以为眷思量编码不同,就听朋友建议,换了法治社会,觉得一定不会屏蔽哈哈哈
结果像这样(请认真阅读红线部分哈哈哈,没错,世另我了)
三、问题记录
在数据爬取阶段,我先通过Python Console 测试是否获取当前路径,并打印当前路径,同时测试爬取一页的结果,显示没有问题。之后我运行程序,发现我建好的文件夹中没有html文件!!!一顿查找,终于发现了是因为Python Console和shujupaqu.py文件不在同一个路径下方,因此新建的“眷思量”文件夹也不一样!,打开./venv(实际所在文件路径),果然发现了html文件的文件夹。
关于venv (我也不清楚是什么时候装的,之前用scrapy 做过图片网站的爬取,可能是看参考书设置的。)具体来说,venv一个虚拟出来的环境。通俗的来讲,这个虚拟的环境可以理解为一个“容器”,在这个容器中,可以只安装我们需要的依赖包,而且各个容器之间互相隔离,互不影响。这样也就更方便使用python2和python3了。
VirtualEnv可以搭建虚拟且独立的python运行环境, 使得单个项目的运行环境与其它项目独立起来。同时也可以用于在一台机器上创建多个独立的python运行环境,VirtualEnvWrapper为前者提供了一些便利的命令行上的封装。 Virtualenv是一个非常好的virtual python environment builder,它最大的好处是,可以让每一个python项目单独使用一个环境,而不会影响python系统环境,也不会影响其他项目的环境。 Virtualenv可用于创建独立的Python环境,在这些环境里面可以选择不同的Python版本或者不同的Packages,并且可以在没有root权限的情况下在环境里安装新套件,互相不会产生任何的影响。
在数据预处理阶段,其实也没怎么找出原来的错误在哪里(憨憨挠头),当时运行程序报错大概是这个地方raise JSONDecodeError(“Expecting value”, s, err.value) from None,这里第一次我在json.load里卖面添加了strict=False 属性,但是单改这个没有用。第二次我开始尝试了别人成功运行的代码仅仅更改路径,也没有解决问题。后来换了关键词“法治社会”,莫名其妙就过了,后面更改的地方就是小修一下items和item具体的关键词名称(我少打了cards的s)和表单循环(我竟然之前生成了66个表格哈哈哈)。换关键词成功生成表单之后,我又一次尝试眷思量,嗯,成功了。
四、总结反思
总的来说,虽然代码总量肯定是很少的,但是很多东西我都不了解,正好这段时间在准备考一下C1认证,对于HTTP协议、Web基础和JAVA要求都还比较基础(对我来说还是有点困难),这段时间会记录一下学习过程和总结反思,尽快实现眷思量超话分析目标!加油!
|