admin管理员组

文章数量:1660709

本文主要讲,用户输入标签后,通过爬虫,可实现获取相关的新闻,将获取的新闻保存为.csv文件。

前期准备

首先导入需要的第三方库

import requests
import time
import random
import json
import pandas as pd

以‘爱国’标签为例,获取的网址为:https://www.toutiao/api/search/content/?aid=24&app_name=web_search&offset=0&format=json&keyword=%E7%88%B1%E5%9B%BD&autoload=true&count=20&en_qc=1&cur_tab=1&from=search_tab&pd=synthesis&timestamp=1569648697670】

我们可以发现中间有一个keyword,经验告诉我们,这个就是标签,我们需要改变的的也正是这个,同时我们也该注意到url最后面有一个 timestamp,这个是时间戳,为了避免长时间使用同一个时间戳,这里需要引入time模块,生成一个即时的时间戳。

代码如下:

# 输入标签名
keyword = input('请输入标签名称:')
# 生成时间戳
timestamp = round(time.time()*1000)  
# 生成url
url = f'https://www.toutiao/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&timestamp={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
        }

请求页面和页面解析

'https://www.toutiao/api/search/content/?aid=24&app_name=web_search&offset=0&format=json&keyword=%E6%B3%95%E5%9B%BD&autoload=true&count=20&en_qc=1&cur_tab=1&from=search_tab&pd=synthesis&timestamp=1569650894434'

为例;

我们打开开发者工具点击左边第一个可以看到如下图面:

经过分析,我们可以发现新闻主要在字段'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/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&timestamp={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()

以上就是本期的内容,本文如果存在不足和错误欢迎指出,谢谢大家的阅读!!!

本文标签: 头条标签今日新闻