抓取网页数据违法吗(python爬虫爬取网页将特定信息存入excel背景(图))
优采云 发布时间: 2021-12-23 10:15抓取网页数据违法吗(python爬虫爬取网页将特定信息存入excel背景(图))
Python爬虫爬取网页在excel中存储特定信息
背景
1、最近遇到一个需要数据分析的项目,主要是采集和分析网页上需要的信息。当信息量较小时,使用复制粘贴-excel分析更加快捷方便。当数据上升到成百上千的时候,一一复制粘贴,显然会感觉效率低下,操作困难。
2、 之前听说过python爬虫,所以趁着这个机会去试验一下。笔者几年前学过python,有一定的基础。
需求分析:
1、目的:使用python爬虫批量抓取网页中的有效信息,然后将这些信息一一存储在excel中。最后,使用excel对数据进行最终的统计分析。
2、功能需求
a、阅读网页
湾 抓取网页的特定内容
c、将内容按顺序存储在excel中
功能实现
爬虫的本质是编写一个程序,让程序模拟一个人操作浏览器访问网页。本文以豆瓣电影为例,爬取某类电影的排名信息
网络分析
打开豆瓣电影分类排行榜,选择动作片,出现的页面如下。
当页面的进度条拖到底部时,会直接刷新一个新页面,而不是刷新整个页面。这使用了 Ajax Web 动态部分加载技术。
右击下方网页,选择check,切换到Network选项,过滤掉XHR选项
继续拖动进度条到底部,发现刷新了一条请求消息。
双击这个请求,可以看到响应是一个类似json格式的数据,里面的信息对应页面上的电影信息
切换到Headers选项,仔细看看网页的请求界面。如果能找到请求接口,就可以通过python中的请求模块访问该接口。网页反馈类似于json格式的数据。如果这一步行得通,那么下一步就很容易处理了。我们先来看看请求接口。
可以看到,请求的地址为%3A90&action=&start=100&limit=20,请求方式为GET。后面的参数,type,interval_id,action,start,limit。
通过对headers的分析,发现请求中有5个参数。这个参数是什么意思?写python程序时需要给这些参数赋什么值?
其实我们需要关注的是爬虫返回的数据,我们只需要保证请求命令能够正常接收到反馈即可。所以我们只需要找出这个请求中改变了哪些参数,然后分析这个参数的含义。对于常量参数,只需填写程序中的页眉即可。
查找更改的参数,只需下拉进度条即可查看新的请求数据
可以看到,只有start变了,start 80;限制 20;开始100;limit 20,你能猜出这20是每次刷新的电影数量吗?开始是从哪个排名电影开始看?
通过对网页的初步分析,这种可能性非常大,验证起来也很简单。记住里面的请求是GET,然后就可以用浏览器直接访问界面验证了。
start=1 limit=2,刷新了两部电影,这个杀手不太冷七武士
start=2 limit=3,刷新了七武士、咕噜和蝙蝠侠:黑暗骑士三部电影。由此可以验证 start 是排名中第一个开始请求的电影。limit 是每次请求的视频数量。如果我想抓取前300个视频,我只需要start=1和limit=300。网页分析到这里就够了,我们得到了我们想要的信息
1、接口:%3A90&action=&start=2&limit=3
2、请求方式:GET
3、参数:type interval_id action start limit 前三个是固定的
概括:
1、 本节通过对网页的分析,发现豆瓣视频排名使用了网页部分动态加载技术
2、 在检查中过滤掉了动态加载的请求接口,请求的反馈是json-like格式(用于后面python解析),通过猜测和直接调用接口的含义找到了 start 和 limit 两个参数
Python代码编写
1、User_agent 介绍
如果你是豆瓣网站的开发者,你是否希望别人用非正式的方式批量抓取你的网站中的数据?想了想,答案肯定是否定的。那么网站服务器是如何判断当前访问合法的呢?最基本的方式是使用请求载体的标识信息User_agent。不同的浏览器有不同的识别信息。
以下是作者谷歌浏览器的识别信息。所以为了防止编写的程序被服务器拒绝访问,在使用请求模块进行请求时必须携带标识信息。
2、代码
先直接上传代码,和excel数据
```python
#!/user/bin/env python
# -*- coding:utf-8 -*-
#UA:User-Agent(请求载体的身份标识)
#UA检测,网站检测到UA不是正常浏览器身份标识,则服务器端很有可能会拒绝该请求
#UA伪装,让爬虫对应的请求载体UA标识伪装成某一浏览器
#解析豆瓣电影
#页面局部刷新 XHR请求
import requests
import json
import xlwings as xw
# 指定url,发起请求,获取响应数据,存储
if __name__ == "__main__":
#UA:将对应的User_Agent封装到一个字典中
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'
}
url= "https://movie.douban.com/j/chart/top_list"
start_num = input("enter start num:")
limit_num = input("enter limit num:")
param = {
'type': '5',
'interval_id': '100:90',
'action':'',
'start': start_num,
'limit': limit_num,
}
#处理url携带的参数:封装到字典中
response = requests.get(url=url, params=param,headers = headers)
# print(response.text)
# ps_name = json.loads(response.text).get('ps_name')
# print('\r\n',ps_name)
#确认服务器返回的json则可以使用json
dic_obj = response.json()
# json_name = json.loads(dic_obj)
app=xw.App(visible=False,add_book=False)
wb=app.books.add()
sht = wb.sheets['Sheet1']
sht.range('A1').value ='序号'
sht.range('B1').value ='排名'
sht.range('C1').value ='名称'
sht.range('D1').value ='评分'
sht.range('E1').value ='上映日期'
sht.range('F1').value ='国家'
i=1
for dic_item in dic_obj:
print('cnt:',i,'title ',dic_item['title'],'\r\n')
sht.range('A'+str(i+1)).value =i
sht.range('B'+str(i+1)).value = dic_item['rank']
sht.range('C'+str(i+1)).value = dic_item['title']
sht.range('D'+str(i+1)).value = dic_item['rating'][0]
sht.range('E'+str(i+1)).value = dic_item['release_date']
sht.range('F'+str(i+1)).value = dic_item['regions'][0]
i +=1
wb.save('movie_rank.xlsx')
wb.close()
app.quit()
执行一下,程序已经在正确输出信息了
打开生成的excel,需要的信息已经生成,剩下的分析就看你的excel能力了
如果改进了程序,分析页面,发现type是对应的电影类型,5:动作;11:情节。可以把所有的类型都试一下,放到字典里,实现某类电影的指定抓拍。作者所完成的是动作电影的捕捉。
代码分析
使用的模块
requests
json
xlwings
requests是网络请求的库,xlwings是操作excel的库,支持xlxs格式的文件。
#UA:将对应的User_Agent封装到一个字典中
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'
}
url= "https://movie.douban.com/j/chart/top_list"
start_num = input("enter start num:")
limit_num = input("enter limit num:")
param = {
'type': '5',
'interval_id': '100:90',
'action':'',
'start': start_num,
'limit': limit_num,
}
这部分是定义头部、访问接口和参数。更改后的参数由终端输入。
#处理url携带的参数:封装到字典中
response = requests.get(url=url, params=param,headers = headers)
使用get命令访问,部分网页可能会使用post,需要与网页的实际请求方式一致。浏览器地址栏只能实现get请求,post请求可以用postman等工具验证
dic_obj = response.json()
# json_name = json.loads(dic_obj)
app=xw.App(visible=False,add_book=False)
wb=app.books.add()
sht = wb.sheets['Sheet1']
sht.range('A1').value ='序号'
sht.range('B1').value ='排名'
sht.range('C1').value ='名称'
sht.range('D1').value ='评分'
sht.range('E1').value ='上映日期'
sht.range('F1').value ='国家'
i=1
for dic_item in dic_obj:
print('cnt:',i,'title ',dic_item['title'],'\r\n')
sht.range('A'+str(i+1)).value =i
sht.range('B'+str(i+1)).value = dic_item['rank']
sht.range('C'+str(i+1)).value = dic_item['title']
sht.range('D'+str(i+1)).value = dic_item['rating'][0]
sht.range('E'+str(i+1)).value = dic_item['release_date']
sht.range('F'+str(i+1)).value = dic_item['regions'][0]
i +=1
wb.save('movie_rank.xlsx')
wb.close()
app.quit()
这部分实现了,读取返回的json格式数据,转换后的数据其实就是一个字典。
操作excel的5个步骤
1、创建APP
2、创建书籍
3、创建工作表页面
4、数据写入
5、保存并关闭
sht.range('A1').value='序列号'
表示将序列号写入单元格A1。如果需要写到B10,把上面的A1改成B10,操作起来很方便。