软件:charles、pyCharm
使用charles获取json的url
代码:
from urllib.requestimport urlopen,Request
import json,collections,chardet
from bs4import BeautifulSoup
import os,csv
#获取要请求的json的url,返回全部url队列
# url中有两个参数一个为start代表从第几条json开始获取,一个为limit代表依次获取几条json数据
# queue长度为13,每次可获取20条json数据
def get_url():
queue = collections.deque()#存储url的队列
head =r'https://movie.douban.com/j/chart/top_list?' \
r'type=11&interval_id=100%3A90&action=&start='
tail =r'&limit=20' # 一共抓取572条json数据,一共抓取13次,每次抓取20个
for iin range(0,573,20):
url = head +str(i) + tail
queue.append(url)
return queue
# 传入url队列,通过url请求json数据,以列表形式返回所有json数据
# 每次返回一个url请求获取的json数据,就是说每次获取20条json数据
def url_get_json(queue):
while queue:# 只要url队列不为空就一直执行
url = queue.popleft()
head = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'}
request = Request(url,headers=head)
html = urlopen(request).read().decode('utf-8')
json_text = json.loads(html)
return json_text,queue
# 处理每条json数据将列表转为字符串,以便存储为csv格式
def handel_value(json_value):
new_json_value = []# 存储最后处理完成的数据
for itemin json_value:
if type(item)is list:# 将列表形式的数据转为字符串
item =' '.join(item)
if type(item)is str:# 处理不能编码为gbk格式的数据
# 比如ööÁýÓçööäñ•öÁäñïïÁ
item =list(item)
length =len(item)
while length:
for jin item:
try:
j.encode('gbk')
except:
item.remove(j)
print(j)#打印不能编码的字符串
length -=1
item =''.join(item)
new_json_value.append(item)#将处理过后的文字放入列表
return new_json_value#返回一条json数据
# 处理json数据,每次处理一条20个json数据,最后一条不满20
def handle_data(json_text):
# json_key = [] # 类别
json_value = []# 数据
abs_path = os.path.join(os.path.abspath('.'),'douban.csv')#文件存储路径
for itemin json_text:#处理每条json数据
# json_key = list(item.keys())
json_value =list(item.values())
new_json_value = handel_value(json_value)#处理数据
try:
with open(abs_path,'a',newline='')as f:#写入数据
writer = csv.writer(f)
writer.writerow(new_json_value)
except:
print(new_json_value)# 打印没有成功存入的json
# 主函数
def main():
queue = get_url()#获取要爬取的url
while queue:
json_text,queue = url_get_json(queue)
handle_data(json_text)
return True
if __name__ =='__main__':
main()