本文主要讲,用户输入标签后,通过爬虫,可实现获取相关的新闻,将获取的新闻保存为.csv文件。
前期准备
首先导入需要的第三方库
import requests
import time
import random
import json
import pandas as pd
我们可以发现中间有一个keyword,经验告诉我们,这个就是标签,我们需要改变的的也正是这个,同时我们也该注意到url最后面有一个 timestamp,这个是时间戳,为了避免长时间使用同一个时间戳,这里需要引入time模块,生成一个即时的时间戳。
代码如下:
# 输入标签名
keyword = input('请输入标签名称:')
# 生成时间戳
timestamp = round(time.time()*1000)
# 生成url
url = f'https://www.toutiao.com/api/search/content/?aid=24&app_name=web_search&offset=0&format=json&keyword={keyword}&autoload=true&count=20&en_qc=1&cur_tab=1&from=search_tab&pd=synthesis×tamp={timestamp}'
headers的伪装
今日头条的反爬挺厉害的,如果headers中不传入cookie,是无法多次都返回我们需要的新闻内容的,而cookie的获取有简单的方式就是复制粘贴;即打开一个标签的文章,打开开发者工具,在headers中复制cookie,如图;
headers的伪装代码如下:
UserAgent_list = ['Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',
'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36']
Cookie = 'tt_webid=6741334664763835907; WEATHER_CITY=%E5%8C%97%E4%BA%AC; ' \
'tt_webid=6741334664763835907; csrftoken=af5535d3c7e019b988ec0f93b7f1774d; ' \
's_v_web_id=9985dd97ccfd39b145674d0955a295a1; ' \
'__tasessionId=pj925vib61569648686929'
headers = {
'User-Agent': random.choices(UserAgent_list), # 使用random模块中的choices()方法随机从列表中提取出一个内容
'Cookie': Cookie
}
请求页面和页面解析
以
为例;
我们打开开发者工具点击左边第一个可以看到如下图面:
经过分析,我们可以发现新闻主要在字段'data'中:
需要注意的是:data中并非所有都是新闻,最后我发现当出现‘abstract’这个字段时,一定是新闻,这里可以借此加一个判断
点开data中的其中一个内容,如图:
而我们需要的提取的内容分别就是字段:abstract,articleurl,commentscount,datetime,read_count,title
代码实现:
response = requests.get(url, headers=headers)
response.encoding = 'utf-8'
news_json = json.loads(response.text)
news_data = news_json['data']
# 创建相关的列表来保存相关的内容
title_list = []
news_content_list = []
news_time_list = []
read_count_list = []
comment_count_list = []
news_url_list = []
news_keyword_list = []
# 遍历news_data,提取相关的内容
for news in news_data:
# 加入一个判断条件,判断是否为新闻
if 'abstract' in news.keys():
# 标题
title_list.append(news['title'])
# 新闻内容
news_content_list.append(news['abstract'])
# 发布时间
news_time_list.append(news['datetime'])
# 阅读量
read_count_list.append(news['read_count'])
# 评论数
comment_count_list.append(news['comment_count'])
# 新闻链接
news_url_list.append(news['article_url'])
# 新闻关键字
news_keyword_list.append(news['keyword'])
# 将获取的内容组成字典
news_info_dict = dict()
news_info_dict['title'] = title_list
news_info_dict['content'] = news_content_list
news_info_dict['read_count'] = read_count_list
news_info_dict['news_time'] = news_time_list
news_info_dict['comment_count'] = comment_count_list
news_info_dict['news_url'] = news_url_list
news_info_dict['news_keyword'] = news_keyword_list
新闻内容的保存
使用pandas库的to_csv来保存成.csv文件
代码如下:
news_DF = pd.DataFrame(news_info_dict)
news_DF.to_csv(self.keyword+'标签的新闻内容.csv', mode='a', encoding='utf_8_sig') # 如果使用‘utf-8’编码,还出现中文乱码,建议使用'utf_8_sig'
print('文件保存成功!!')
完整代码
上面的是按顺序执行下来的,而完整代码我是用面向对象的编程方式(即使用类)
完整代码如下:
# 导入所需的库
import requests
import json
import pandas as pd
import time
import random
class toutiao_spider():
def __init__(self, keyword):
# 标签名
self.keyword = keyword
# 生成一个13位的时间戳
self.timestamp = round(time.time()*1000)
def get_headers(self):
"""
headers伪装:User-Agent和Cookie
:return: headers
"""
UserAgent_list = ['Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',
'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36']
Cookie = 'tt_webid=6741334664763835907; WEATHER_CITY=%E5%8C%97%E4%BA%AC; ' \
'tt_webid=6741334664763835907; csrftoken=af5535d3c7e019b988ec0f93b7f1774d; ' \
's_v_web_id=9985dd97ccfd39b145674d0955a295a1; ' \
'__tasessionId=pj925vib61569648686929'
headers = {
'User-Agent': random.choices(UserAgent_list)[0], # 使用random模块中的choices()方法随机从列表中提取出一个内容
'Cookie': Cookie
}
return headers
def get_news_info(self, json_data):
"""
传入json格式的内容,对内容进行提取:分别提取新闻的标题及内容,发布日期,阅读量,评论数,新闻url,新闻所属的关键字
:param json_data: json格式的文本
:return: news_info_dict
"""
# 将json格式转化为字典格式
dict_data = json.loads(json_data, encoding='utf-8')
# 新闻的主要内容都在dict_data中的data字段中
news_data = dict_data['data']
# 创建相关的列表来保存相关的内容
title_list = []
news_content_list = []
news_time_list = []
read_count_list = []
comment_count_list = []
news_url_list = []
news_keyword_list = []
# 遍历news_data,提取相关的内容
for news in news_data:
# 加入一个判断条件,判断是否为新闻
if 'abstract' in news.keys():
# 标题
title_list.append(news['title'])
# 新闻内容
news_content_list.append(news['abstract'])
# 发布时间
news_time_list.append(news['datetime'])
# 阅读量
read_count_list.append(news['read_count'])
# 评论数
comment_count_list.append(news['comment_count'])
# 新闻链接
news_url_list.append(news['article_url'])
# 新闻关键字
news_keyword_list.append(news['keyword'])
# 将获取的内容组成字典
news_info_dict = dict()
news_info_dict['title'] = title_list
news_info_dict['content'] = news_content_list
news_info_dict['read_count'] = read_count_list
news_info_dict['news_time'] = news_time_list
news_info_dict['comment_count'] = comment_count_list
news_info_dict['news_url'] = news_url_list
news_info_dict['news_keyword'] = news_keyword_list
return news_info_dict
def save_to_csv(self, news_info_dict):
"""
使用pandas中的to_csv()将新闻内容保存为.csv 文件
:param news_info_dict: 新闻内容字典
:return:
"""
news_DF = pd.DataFrame(news_info_dict)
news_DF.to_csv(self.keyword+'标签的新闻内容.csv', mode='a', encoding='utf_8_sig') # 如果使用‘utf-8’编码,还出现中文乱码,建议使用'utf_8_sig'
print('文件保存成功!!')
def get_response(self):
"""
请求页面
:return:json_data
"""
# 拼接url
url = f'https://www.toutiao.com/api/search/content/?aid=24&app_name=web_search&offset=0&format=json&keyword={self.keyword}&autoload=true&count=20&en_qc=1&cur_tab=1&from=search_tab&pd=synthesis×tamp={self.timestamp}'
# 获取headers
headers = self.get_headers()
# 请求页面
response = requests.get(url=url, headers=headers)
if response.status_code == 200:
print('请求成功!!')
else:
print('请求失败,正在尝试发起请求!!')
self.get_response()
json_data = response.text
return json_data
def run(self):
"""
主运行函数
:return:
"""
json_data = self.get_response()
news_info_dict = self.get_news_info(json_data)
self.save_to_csv(news_info_dict)
if __name__ == '__main__':
spider = toutiao_spider(keyword='爱国')
spider.run()
以上就是本期的内容,本文如果存在不足和错误欢迎指出,谢谢大家的阅读!!!