网络数据采集 —— 爬虫(3)
3.JSON
JSON ------>JavaScript Object Notation-------->两个系统间交换数据的一种格式(事实标准)
-
JSON格式的数据是纯文本,任何系统,任何编程语言都能够处理纯文本,所以JSON特别适合在异构的系统(硬件不同、操作系统、编程语言不同)之间交换数据
- XML--------> eXtensible MarKup Language ----------->可拓展标记语言
- JSON-----> Python-------->dict
- YAML ----->Yet Anthor Markup Language
json模块 ----->实现Pthon中的字典和JSON格式字符串的双向转换
-
~dumps / dump ------>把字典变成字符串/直接把字典直接写到文件里面
- loads / load-------> 把字符串还原成字典/直接从文件里读字符串还原成字典
import json
person_info = {
"name": "啊呀",
"age":22,
"fhduhh":'hbjhb',
"car":{"brand":"宝马"
"date":"1985-6-24"
"max_speed":"80"}
"jnfkj":'hjbkjh'}
with open('person.json ', 'w', encoding= 'utf-8') as file:
json.dump(person_info, file) # 写进文件
with open('person.json', 'r') as file:
person_info = json.load(file)
print(type(person_info)) # class dict
print(person_info) # 读文件
2.服务器如何识别用户是否登录
1.第一种
用户登录成功后,服务器端会创建一个对象,这个对象里面就保存了用户相关的数据。
这个对象我们通常称之为(Seession会话对象),服务器除了创建保留这个会话对象之外。
还会在响应中要求浏览器记录一条Cookie数据,Cookie中保存了会话对象的ID(标识符),
下次请求的时候,在HTTP请求中携带Cookie数据,服务器就会获取到会话的ID,
这样的话,服务器根据这个ID就可以找到之前为用户创建的会话对象,里面就是用户的信息。
2.第二种
用户登录成功后,服务器端不保存任何对象,但是服务器端会将用户的数据生成一个身份令牌,然后将身份令牌返回给浏览器(可以保存在Cookie中,也可以保存在其他的浏览器本地存储中),下一次请求的时候,在请求头中带上这个身份令牌(Authentication),服务器睹其身份令牌,获取用户身份令牌中的数据来判断用户是否已然登录。
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
'AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/88.0.4324.192 Safari/537.36',
'Cookie': '....'
}
浏览器本地存储技术:
Cookie(最多,兼容性最好)
网页右击 ——> 检查 ——> Network ——>Cookie
LocalStorage / sessionStorage
IndexedDB(嵌入式的数据库)
3.使用商业IP代理 -------> 高匿代理
隐匿自己的身份
突破网站对访问IP段的限制
通过多个IP代理轮流使用,避免一个IP地址被封禁或者限速
商业IP代理哪家强?
可用性、访问速度、价格
蘑菇代理、芝麻代理、快代理、讯代理、阿布云代理
查看自己的IP地址可以百度IP地址可以获得本机的IP地址(用来绑白名单)
完成订单之后点击生成API返回API接口,自己可以设置JSON格式或者TXT纯文本
之后生成一个URL,请求之后会返回一组代理,
IP:''(就是代理服务器的IP地址)
port:''(就是服务器的端口)
从商业IP代理获取代理服务器地址并保存文件
在商业爬虫项目中,使用IP代理时,通常是需要先建立一个代理池
加载代理服务器并保存
监控所有代理服务器,及时移除失效的服务器
提供一个接口能够随机选中某个代理服务器
import random
import bs4
import requests
import openpyxl
headers = {
'User-Agent': '------------',
}
all_proxies = []
def load_proxies():
"""通过蘑菇代理获取代理服务器信息"""
global all_proxies
while True:
resp = requests.get(
'http://piping.mogumiao.com/proxy/api/get_ip_bs?'
'appKey=20c3b5de1fa14df7baeb608aa09971de&count=5&expiryDate=0&format=1&newLine=2'
)
data = resp.json()
if data['code'] == '0':
all_proxies = data['msg']
def fetch_movie_detail(url):
"""根据指定的URL抓取电影的详情信息(类型和时长)"""
# 随机选中一个代理服务器
proxy = random.choice(all_proxies)
resp = requests.get(url=url, headers=headers, proxies={
'http': f'http://{proxy["ip"]}:{proxy["port"]}',
'https': f'http://{proxy["ip"]}:{proxy["port"]}'
})
soup = bs4.BeautifulSoup(resp.text, 'html.parser')
genre_spans = soup.select('span[property="v:genre"]')
runtime_span = soup.select_one('span[property="v:runtime"]')
gener = '/'.join([genre_span.text for genre_span in genre_spans])
runtime = runtime_span.attrs['content']
return [gener, runtime]
def main():
# 首先通过商业IP代理加载代理服务器
load_proxies()
# wb = xlwt.Workbook()
wb = openpyxl.Workbook()
# sheet = wb.add_sheet('Top250')
sheet = wb.create_sheet('Top250')
row_no = 0
column_names = ('编号', '片名', '评分', '名句', '类型', '时长')
for col, column_name in enumerate(column_names):
# sheet.write(row_no, col, column_name)
sheet.cell(row_no + 1, col + 1, column_name)
try:
for page in range(1):
# 随机选中一个代理服务器
proxy = random.choice(all_proxies)
resp = requests.get(
url=f'https://movie.douban.com/top250?start={page * 25}',
headers=headers,
proxies={
'http': f'http://{proxy["ip"]}:{proxy["port"]}',
'https': f'http://{proxy["ip"]}:{proxy["port"]}'
}
)
if resp.status_code == 200:
soup = bs4.BeautifulSoup(resp.text, 'html.parser')
anchors = soup.select('div.info > div.hd > a')
title_spans = soup.select('div.info > div.hd > a > span:nth-child(1)')
rating_spans = soup.select('span.rating_num')
quote_spans = soup.select('p.quote > span')
for anchor, title_span, rating_span, quote_span in zip(anchors, title_spans, rating_spans, quote_spans):
row_no += 1
detail_url = anchor.attrs['href']
movie_infos = [row_no, title_span.text, rating_span.text, quote_span.text]
movie_infos += fetch_movie_detail(detail_url)
print(movie_infos)
for col, info in enumerate(movie_infos):
# sheet.write(row_no, col, info)
sheet.cell(row_no + 1, col + 1, info)
else:
print(f'请求失败,响应状态码:{resp.status_code}')
except Exception as err:
print(err)
finally:
wb.save('豆瓣电影.xlsx')
if __name__ == '__main__':
main()
4.调用三方服务------> 自己的程序解决不了的问题就可以依赖三方服务
-
~ 免费
- 付费
数据聚合服务 ----------> 把常用的服务整合到一起
juhe.cn
tianapi.com(基本不花钱)