Python爬⾍实例(五):爬取XX⽹站电视剧json格式数据
本⽂结合之前的练习,完成项⽬⽬标:爬取XX⽹站的电视剧json数据。
项⽬思路
⾸先发送cookie请求爬取登录后的内容(具体⽅法见),发送请求时加⼊超时错误重试功能(具体⽅法见);成功登录后,发送get请求,
利⽤json.loads和json.dumps⽅法爬取电视剧数据,并保存到本地html⽂件。
该项⽬使⽤到以下⼏个模块,所以先在项⽬开头导⼊
# 【加载所需模块】
import requests
from retrying import retry
import json
import os
⾸先定义⼏个url地址,以便后续使⽤。url1是登录界⾯的地址,url2是登录成功后个⼈主页的地址,url3是美剧的请求地址。
class DoubanTVSpider:
def __init__(self): # 初始化⼀个类python请求并解析json数据
然后,定义⼏个函数,发送post请求获取登录后的内容。利⽤@retry 装饰器修饰_post_request函数,该函数发送get请求时进⾏了超时
限制timeout=1,如果请求时间超过1秒,则会重新发送请求,两次请求之间等待1000毫秒,最⼤尝试10次之后停⽌。该函数实例化了⼀
个叫做post_session的session,设置在本地的cookie会保存在post_session中,其中设置请求体data=post_data参数时,需带上登录
该⽹站的账号和密码。
post_request函数则尝试捕获异常。先尝试执⾏try后⾯的请求,如果报错,则会被except捕获,返回post请求失败信息。
# POST请求,获取登录后的页⾯数据
@retry(stop_max_attempt_number=10, wait_fixed=1000)
def _post_request(self, post_url, get_url_mine, post_data, post_headers):
post_session = requests.session()
post_session.post(post_url, data=post_data, headers=post_headers)
post_response = (get_url_mine, headers=post_headers, timeout=1)
return t.decode()
def post_request(self, post_url, get_url_mine, post_data, post_headers):
try:
post_res = self._post_request(post_url, get_url_mine, post_data, post_headers)
# print('POST Request Content:\n', post_res)
except Exception:
post_res = 'Post Request Failed.'
return post_res
接着把爬取的内容或错误信息保存到本地的html⽂件中。
def save_post_data(self, post_res):
try:
with open('douban_post_res.html', 'w', encoding='utf-8') as f:
f.write(post_res)
print('Save Post Data Successfully.')
except(IOError, TimeoutError):
print('Save Post Data Failed.')
然后,再⽤与上述post请求类似的⽅式发送get请求get_request_2,返回解码后的内容get_str。parse_data是对解码后内容进⾏解析的函数。json.loads()⽅法将get请求获取的字符串转换为字典,再提取想要的相应信息,“subject_collection_items”中保存美剧的相应信息,total是美剧总的条⽬数量,count则是每页条⽬的数量。例如美剧共有100条数据,每页展⽰20条,分为5页。因此需要循环5次发送请求获取内容信息。total和count就是控制循环的变量。
接下来是保存数据,保存之前先调⽤file_exit_dec函数检测本地⽂件是否存在,确保删除了之前的数据后再进⾏保存。由于list_data是⼀个列表,所以需要将列表中的每⼀个元素都⽤json.dumps()⽅法转换为字符串,才可以写⼊本地⽂件。
def parse_data(self, get_str):
list_s1 = json.loads(get_str)
list_s2 = list_s1['subject_collection_items']
total = list_s1['total']
count = list_s1['count']
return list_s2, total, count
def file_exit_dec(self, file_name):
try:
0到999传递的是哪个数字except IOError:
mongodb菜鸟print('File does not exit, now you can append the file by "with open"! ')
def save_data(self, list_data, file_name):
try:
with open(file_name, 'a', encoding='utf-8') as f:
for list_ele in list_data:
str_ele = json.dumps(list_ele, ensure_ascii=False)
f.write(str_ele)
f.write(',\n')
print('Save Data Successfully!')
except(IOError, Exception):
print('Failed Saving The Data.')
最后,定义程序主体,按照以上步骤调⽤函数,再调⽤主程序。
def run(self): # 程序主体
# ******************************************************************************************************
# POST请求,获取登录⾖瓣后的页⾯数据
# 1、POST请求数据准备
print('*'*100)manager是什么意思
post_url = p_url1
get_url_mine = p_url2
post_headers = {'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Mo post_data = {'ck': '', 'redir': 'm.douban', 'name': 'aaa', 'password': 'bbb'}
# 2、POST请求登录
post_res = self.post_request(post_url=post_url, get_url_mine=get_url_mine, post_data=post_data, post_headers=post_headers)
# 3、POST数据保存
self.save_post_data(post_res)
# ******************************************************************************************************
# GET请求,获取⾖瓣电视剧的数据
# 1、GET请求数据准备
print('\n', '*'*100, '\n')
headers = {'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Mobile S 'Referer': 'm.douban/tv/american'}
get_cookie = 'bid=aaa; douban-fav-remind=bbb; __utmc=ccc; …………'
cookie_para = {get_co.split('=')[0]: get_co.split('=')[1] for get_co in get_cookie.split('; ')}
start = 0
total = 20
count = 0
get_file_name = 'json_douban_tv.html'
self.file_exit_dec(get_file_name)
throwable英语while start < total+count:
get_url = p_url3.format(start)
# 2、发送请求,获取响应
get_str = _request_2(get_url, headers, cookie_para)
# 3、提取数据
list_s, total, count = self.parse_data(get_str)
# 4、保存数据
self.save_data(list_s, get_file_name)
# 5、准备下⼀次url
start += count
if __name__ == '__main__':
tecent = DoubanTVSpider()
tecent.run()
如果觉得内容不错,请扫码关注,获取更多内容
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论