【python爬虫】8.温故而知新

2023-11-16

前言

Hello又见面了!上一关我们学习了爬虫数据的存储,并成功将QQ音乐周杰伦歌曲信息的数据存储进了csv文件和excel文件。

学到这里,说明你已经成功入门了Python爬虫!

今天就让我用一个实操项目带你复习之前1-7关所学的知识。这个项目爬取的主题是:美国总统特朗普……

美国总统特朗普之前频上热搜,出于好奇,我对他的相关时事在今日头条网站上进行了爬取,发现他果然是语出惊人。

相信你对这个项目一定充满了期待,但在此之前,按照国际惯例,我们先来回顾一下之前的知识。

回顾前路

在前面,我们所有学习的知识都可以用【项目实现】和【知识地图】两张图来说清。

【项目实现】: 任何完成项目的过程,都是由以下三步构成的。

在这里插入图片描述
先需要明确自己的目标是什么,然后分析一下如何实现这个目标,最后就可以去写代码了。

当然,这不是一个线性的过程,而可能出现“代码实现”碰壁后然后折返“分析过程”,再“代码实现”的情形。

接下来是【知识地图】:前面7关所讲的爬虫原理,在本质上,是一个我们所操作的对象在不断转换的过程。

在这里插入图片描述
总体上来说,从Response对象开始,我们就分成了两条路径,一条路径是数据放在HTML里,所以我们用BeautifulSoup库去解析数据和提取数据;另一条,数据作为Json存储起来,所以我们用response.json()方法去解析,然后提取、存储数据。

你需要根据具体的情况,来确定自己应该选择哪一条路径。

也可以参考图片上的注释,帮助自己去回忆不同对象的方法和属性。不过,老师还是希望你能把这个图记在心里。

好啦,1-7关的内容就梳理完成啦~

接下来到我们今天的任务了,在头条中爬取一下关于特朗普的相关信息。

代码实现

体验代码

了解时事最快的渠道莫过于新闻了,而将各个新闻网数据自动收集起来的今日头条也就这么顺理成章成为我们的今日目标了。

在这里我决定以头条上搜索特朗普:的结果作为我们爬虫爬取的目标。

代码已经写好了,我们先来体验一下效果吧。

阅读下面的代码,然后点击运行。提示:由于网址反爬策略升级的问题,如果本地运行代码报错,请及时留言求助。

import requests
import csv

# 新建csv文件并打开文件
file = open('articles.csv', 'w', newline='', encoding='utf-8')
writer = csv.writer(file)

# 写入表头
writer.writerow(['标题', '链接'])

# 设置爬取链接
url = 'https://www.toutiao.com/api/search/content/'

# 设置 offset 的起始值为 0
offset = 0

# 循环三页
while offset < 60:
    # 封装参数
    params = {'aid': '24', 'app_name': 'web_search', 'offset': offset, 'keyword': '特朗普:', 'count': '20'}

    # 发送请求,并把响应内容赋值给变量 res
    res = requests.get(url, params=params)

    # 使用 json 方法将响应结果读成字典
    articles = res.json()

    # 取出 data 对应的值
    data = articles['data']

    # 遍历 data 内容
    for i in data:

        # 判断这行内容是不是文章
        if i.get('article_url'):

            # 取出这行内容,放到列表里
            row = [i['title'], i["article_url"]]

            # 打印内容
            print(row)

            # 写入这行内容
            writer.writerow(row)

    # 换页
    offset = offset+20

# 关闭文件
file.close()

可以看到最近特朗普相关新闻的标题与链接都被爬取下来了。

接下来就跟着我一步步来实现这个代码吧。

功能拆解

写代码时我们首先要明确目标,毕竟任何代码都是为了解决问题而去写的。

这次我们的任务是专门爬取找特朗普热点新闻的链接和标题。爬取多少呢,先定一个小目标,爬它60条左右吧。

注:爬取几万条数据当然是可以的,不过毕竟参加课程的同学有很多,每个人都去爬个一千条数据都有着百万爬取量了,如此高频的访问会给对方的服务器造成相当大的压力。为了不竭泽而渔,我们需要控制好在课堂里的爬取数量。

有了目标,接下来我们就需要分析如何去实现它了。

爬虫的本质是通过代码来模拟真人访问浏览器的过程,所以想一想,如果不借助代码的话,我们一般会如何去查看60条今日头条上特朗普相关新闻呢?

1.打开浏览器。

2.打开今日头条网页。

3.在今日头条中搜索"特朗普:",查看搜索结果。

4.点击网页下方的翻页,直到加载出60条数据。

5.打开60个网页,对它们的网址和标题不断进行复制粘贴保存到本地。

我们用爬虫来模拟爬取时也可以根据这些步骤来。

1.在今日头条中搜索"特朗普:",爬取当前界面的数据。

2.解析当前界面数据,分析如何提取出需要的新闻标题和链接。

3.点击加载更多,爬取其中60条数据。

4.将爬取到的数据保存起来。

那么我们先开始获取数据吧。

获取数据

特朗普发言相关新闻的URL在这里:https://www.toutiao.com/search/?keyword=%E7%89%B9%E6%9C%97%E6%99%AE%EF%BC%9A

在这里插入图片描述
这是我做这个项目时,网站显示的内容。

我们直接点击右键——检查——element,来查找一下数据存放标签的规律吧。

可以发现界面上所有的新闻标题都是class属性为title-box标签里的文本内容。

当然还有许多其他的提取方法,不过我们可以先尝试爬取一下。

# 导入模块
import requests
from bs4 import BeautifulSoup

# 发起请求,将响应的结果赋值给变量res。
url='https://www.toutiao.com/search/?keyword=%E7%89%B9%E6%9C%97%E6%99%AE%EF%BC%9A'
res=requests.get(url)
# 用bs进行解析
bstitle=BeautifulSoup(res.text,'html.parser')
# 提取我们想要的标签和里面的内容
title=bstitle.find_all(class_='title-box')
# 打印title
print(title)

运行的结果是一个空列表,这是为什么呢?

一次性写完爬虫代码固然让人舒畅,不过最终运行代码结果和我们预期目标不符时就很尴尬了。

所以在写代码时妙用print语句就很有必要了,这可以很好的帮助我们监测程序运行的过程。

在这里我们可以分别print一下网页源代码和网页访问状态码来查看一下我们爬取的内容与状态。

# 引入requests和bs
import requests
from bs4 import BeautifulSoup

# 发起请求,将响应的结果赋值给变量res。
url='https://www.toutiao.com/search/?keyword=%E7%89%B9%E6%9C%97%E6%99%AE%EF%BC%9A'
res=requests.get(url)
# 用bs进行解析
bstitle=BeautifulSoup(res.text,'html.parser')
# 打印网页源代码
print(res.text)
# 检查状态码
print(res.status_code)

可以发现网页返回状态码是200,说明访问网页成功了,不过爬取出来的内容似乎和我们在网页上看到的不太一样。

出现这种情况,往往说明网页本身是动态网页,需要的数据不在初始的HTML中。

之后你们在实际爬取网站的过程中也可以基于这点来判断:当你直接爬取界面上看到的url,打印出网页访问状态码和网页源代码,当爬取的状态码是200,网页源码内容却与直接从网页上看到的不符时,那么就说明网页是动态网页。

当然,还有一个更加方便的方法,我们可以直接在谷歌浏览器里看出网页是否是动态的。

在这里插入图片描述
在这里插入图片描述
如果preview和网页上看到的内容一致,那么就是静态网页,反之,则是动态网页。

静态网页我们直接爬取当前浏览器上显示的网页就可以了,而对于动态网页,我们的处理就是四步走:右键检查——network——xhr——刷新界面,然后来查找我们需要的数据存放在哪个xhr文件中。

在这里插入图片描述
面对一堆xhr文件该如何快速找到自己想要的那个呢?

对于经验丰富的爬虫工程师来说,看xhr之中的文件名可以更快看出数据在哪。

对于现在的我们来说,可以逐个点开xhr文件,通过查看它们的preview来确定数据所在的xhr位置。

这个方法虽然简单,但却很有效。

在这里插入图片描述
在头条网的三个xhr中,可以很明显的通过preview来看到,我们想要的数据肯定在第一个xhr里,毕竟另外两个xhr里的内容一眼就看穿了。

接下来就是在这个xhr里找到我们想要的新闻标题与链接的位置规律,并将它们提取出来。

解析提取数据

浏览一下这个xhr的preview,通过在preview里搜索在界面上看到的新闻标题来查看这个json文件的结构。

在这里插入图片描述
搜索到的每一个标题存放的位置都有很多,为了方便,我们直接通过xhr文件中data大列表里每个字典的title键来提取。

关于网址我们也如法炮制,在preview中搜索url关键词。

在这里插入图片描述
好了,找到数据了,我们先将这一页的20个数据爬取下来吧!

还记得如何爬取xhr里对应文件的内容吗?

爬取的网址在Headers中General标题下的Request URL里,其中的url在?问好之前的就是我们爬取的网址。

在这里插入图片描述
?问号之后的是params,params是一种访问网页所带的参数,这种参数的结构,会和字典很像,有键有值,键值用=连接;每组键值之间,使用&来连接。

关于params可以翻到General最下面看到,可以直接复制到代码中。

在这里插入图片描述
记得将直接复制的params转化成字典,字典里每个键值要用逗号隔开。

不断手动加逗号引号的过程似乎很麻烦。

好吧,到了第8关了,也是时候该教你了。

学完这一关就去让你的助教来教你如何将网页上复制的params直接转化成字典的方法吧。

现在,还是老老实实手动转化一遍,因为接下来我们还要继续分析params里部分参数的作用。

# 导入模块
import requests

url = "https://www.toutiao.com/api/search/content/"

# 封装params变量
params = {'aid':'24',
'app_name':'web_search',
'offset':'0',
'format':'json',
'keyword':'新疆棉花',
'autoload':'true',
'count':'20',
'en_qc':'1',
'cur_tab':'1',
'from':'search_tab',
'pd':'synthesis',
'timestamp':'1616756202046',
'_signature':'_02B4Z6wo00f01.cp-ewAAIDAR9gVJnLDqF.3Df1AAJ2h1CoOpRhZZIWXdVjhrG9mY19M0c1RxNSsZ4ViJcNfwF6bsV8e9npvQeENNWcL9cis4wlCeXgdbeIf0W2R.lsi-gP3omstdNnUbJdKec'}


# 发送请求,并把响应内容赋值到变量res里面
res = requests.get(url,params=params)

# 定位数据
articles=res.json()
data=articles['data']

# 遍历data列表,提取出里面的新闻标题与链接
for i in data:
    list1=[i['title'],i["article_url"]]
    print(list1)   

运行结果:

Traceback (most recent call last):
  File "/home/python-class/classroom/apps-2-id-5f56e7f9300055000153a220/93/main.py", line 30, in <module>
    for i in data:
TypeError: 'NoneType' object is not iterable

阿欧,运行出错了。我们来看看报错,KeyError,根据我们的经验,这一般是因为字典中没有要查找的key才会报这个错误。

于是我们在回去仔细检查我们爬取的json文件。

在这里插入图片描述
在这里插入图片描述
结果发现data里的列表有两种,一种是界面包含的新闻信息,一种是特朗普相关周边新闻。

差不多每10个字典里就有一个是特朗普相关周边新闻。

在这些相关周边新闻的字典里,是没有title这个键的。

第4关爬取豆瓣时我们也遇到过类似的问题,爬取下来的列表中有些不是我们想要的元素。

当时我们是用if判断来解决的,在这我们可以尝试用try语句来解决这个问题。

参考答案:(在except后面你可以print任意内容来提示自己这里遇到了特殊列表。)

# 导入模块
import requests

# 定义url,params等变量
url = "https://www.toutiao.com/api/search/content/"
params = {'aid': '24', 'app_name': 'web_search', 'offset': 0, 'keyword': '特朗普:', 'count': '20'}

# 发送请求,并把响应内容赋值到变量res里面
res = requests.get(url,params=params)

# 定位数据
articles=res.json()
data=articles['data']

# 遍历列表,提取出里面的新闻标题与链接
for i in data:
    try:
        list1=[i['title'],i["article_url"]]
        print(list1)
    except:
        print("此处无银三百两")   

接下来我们就需要爬取更多的内容了。

我们尝试人工加载更多数据,会发现xhr里有新的文件跳出来了,查看发现就是新加载出来的20条数据。

仔细对比一下两个xhr的params,发现只有offset参数有些变化,从0变成了20,所以offset这个参数应该是代表一个起始值,代表从哪一篇开始爬取。

如何验证我们的想法呢?当然是上代码了,将offset参数改成0,10,20分别运行一个查看一下最终的结果。

请你运行下面的代码,看到终端提示"通过input来改变offset参数吧"后,输入你想要设置的offset参数(0,10,20)。

import requests
from bs4 import BeautifulSoup
url='https://www.toutiao.com/api/search/content/'
offset = input("通过input来改变offset参数吧")
headers={'sec-ch-ua':'"GoogleChrome";v="89","Chromium";v="89",";NotABrand";v="99"',
'sec-ch-ua-mobile':'?0',
'sec-fetch-dest':'empty',
'sec-fetch-mode':'cors',
'sec-fetch-site':'same-origin',
'user-agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/89.0.4389.90Safari/537.36',
'x-requested-with':'XMLHttpRequest'}
params={'aid':'24',
'app_name':'web_search',
'offset':offset,
'format':'json',
'keyword':'新疆棉花',
'autoload':'true',
'count':'20',
'en_qc':'1',
'cur_tab':'1',
'from':'search_tab',
'pd':'synthesis',
'timestamp':'1616756202046',
'_signature':'_02B4Z6wo00f01.cp-ewAAIDAR9gVJnLDqF.3Df1AAJ2h1CoOpRhZZIWXdVjhrG9mY19M0c1RxNSsZ4ViJcNfwF6bsV8e9npvQeENNWcL9cis4wlCeXgdbeIf0W2R.lsi-gP3omstdNnUbJdKec'}
res=requests.get(url,headers=headers,params=params)
target=res.json()['data']
for item in target:
    try:
        t_title=item['title']
        print(t_title)
    except KeyError:
        pass

运行结果:

通过input来改变offset参数吧20
不容抹黑!关于新疆棉花的六个事实
新疆棉花年产520万吨,占全国产量87%!中国:我们自己都不够用
新疆以前并没有很多棉花,为什么现在成为了主要产棉区?
新疆棉花成为“众矢之的”!为何我国进口棉花却增67%?真相了
播种面积下降,产量却增加!新疆棉花为啥这么牛?
新疆棉花,不是美国刀下的凉粉
“天下棉仓”新疆,棉花为何如此优质?竟然掌控了全球棉花定价
BCI要让新疆的棉花“凉凉”?新疆长绒棉:中国自己还不够用
新疆棉花为啥产量高、质量好?其实,主要原因有三个
上千年种植史、产量全国第一、世界顶级品质……新疆棉花到底有多强?
“抵制新疆棉花”引发众怒:央视起底幕后推手
被打压的新疆棉花,究竟有多牛?
新疆棉花为何被下毒手?背后隐藏美国一盘大棋,若屈服将一败涂地
新疆的棉花好在哪?6张图带你一探究竟
反å»对新疆棉花的抹黑,中国八点破解之道
我们新疆的棉花,是最纯洁、最温暖的花
新疆棉花稳霸热搜!这些冷知识你了解吗?
科普一下,新疆棉花究竟有多厉害,掌握了全球棉花定价权
新华全媒+丨新疆的棉花是怎样种出来的
为什么是新疆?从“人权”到禁新疆棉花,背后的黑手到底看中什么

不出预料,offset果然可以控制从哪篇新闻开始爬。

继续分析params。在一堆英文中,keyword键对应的中文参数特朗普:格外的显眼。

我们也可以合理推断出keyword参数可以控制我们搜索的内容。

为了保险起见,我们还是通过代码来测试一遍吧。跟修改offset一样,我们通过input来控制传入的keyword参数。

请你运行下面的代码,看到终端提示"你想要搜索什么新闻呢?"后,输入你想要搜索的新闻关键字。

# 导入模块
import requests

# 定义url,keyword,params等变量
url = "https://www.toutiao.com/api/search/content/"
keyword = input("你想要搜索什么新闻呢?")
params = {'aid': '24', 'app_name': 'web_search', 'offset': 0, 'keyword': keyword, 'count': '20'}

# 发送请求,并把响应内容赋值到变量res里面
res = requests.get(url,params=params)

# 定位数据
articles=res.json()
data=articles['data']

# 遍历列表,提取出里面的新闻标题与链接
for i in data:
    try:
        list1=[i['title'],i["article_url"]]
        print(list1)
    except:
        pass    

你搜索了什么内容呢

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【python爬虫】8.温故而知新 的相关文章

随机推荐

  • 网络安全渗透测试之pingtunnel使用实验

    目录 一 实验环境准备 二 安装pingtunnel 一 在192 168 101 105 web服务器上安装pingtunnel 三 建立ICMP隧道 一 在web服务器上启动pingtunnel 二 在kali上设置转发 三 隧道渗透演
  • 白盒测试(程序流程图)

    白盒测试又称结构测试 透明盒测试 逻辑驱动测试或基于 代码的测试 白盒测试是一种 测试用例设计方法 盒子指的是被测试的 软件 白盒指的是盒子是可视的 你清楚盒子内部的东西以及里面是如何运作的 白盒 法全面了解程序内部逻辑结构 对所有逻辑路径
  • CBC模式解读

    一 什么是CBC模式 CBC模式的全称是Cipher Block Chaining模式 密文分组链接模式 之所以叫这个名字 是因为密文分组像链条一样相互连接在一起 在CBC模式中 首先将明文分组与前一个密文分组进行XOR运算 然后再进行加密
  • LM算法初识

    由于工作内容接触到点云标定 需要用到最小二乘法 所以特意花了点时间研究LM算法 但是由于大学的高等数学忘得差不多了 所以本文从最基本的一些数学概念开始 信赖域法 在最优化算法中 都是要求一个函数的极小值 每一步迭代中 都要求目标函数值是下降
  • canvas系列教程之填充颜色

    艺术离不开色彩 今天咱们来介绍一下填充颜色 体会一下色彩的魅力 填充颜色主要分为两种 基本颜色 渐变颜色 又分为线性渐变与径向渐变 我们一个个来看 填充基本颜色 Canvas fillStyle属性用来设置画布上形状的基本颜色和填充 fil
  • Python + Django4 搭建个人博客(二十):阿里云部署博客项目

    本篇我们将完成我们搭建个人博客的核心功能的最后一篇 部署上线 接下来部分我们将不定期更新一些其他的博客功能 比如 文章栏目 消息通知 用户扩展等小功能模块 目录 准备服务器 安装Xshell 和Xftp 服务器安装软件 安装Mysql 修改
  • vue-loade和vue的版本问题,webpack5

    npm add D vue template compiler 2 6 14 vue loader 15 9 8 const VueLoaderPlugin require vue loader vue加载器 使用node语法获得动态路径
  • Nginx配置文件详细说明

    原创 http www cnblogs com xiaogangqq123 archive 2011 03 02 1969006 html 在此记录下Nginx服务器nginx conf的配置文件说明 部分注释收集与网络 运行用户 user
  • 微信小程序:自定义导航栏

    看到有的微信小程序的页面左上角有了个 小房子 可以返回首页 这是怎么做到的 其实这是微信开放的自定义的自定义导航栏来完成 但是最开始 对于一个页面很多的小程序 其实有点一言难尽 因为你自定义 你可能要所有页面都要添加一遍 现在小程序可以自定
  • 34. Search for a Range

    这道题一开始没看别人的算法 第一个想法是用递归做 自己憋了两个小时终于憋出来了 然而超时 递归的想法是先用二分法找到一个target 然后从target左右再用二分法找边界 然而 真的是 太慢了 class Solution public
  • VSCode问题记录

    20230304 0 引言 这几年的编程方式还真是各种变化 从一开始直接VIM 到后面使用jupyter进行机器学习相关 然后再过渡到vim的形式并加以tmux批量化 最后去年使用了vscode作为IDE 随着工具的变化 那么很多习惯也都随
  • UnityVR--EventManager--事件中心2

    目录 前言 事件中心的结构 EventManager事件管理器 EventType事件类型 EventListener监听及回调 EventDataBase回调时需要传递的参数 总结 前言 上一篇 事件中心1 中 简单解释了委托 事件 监听
  • 【Java SE】类和对象(全网最细详解)

    点进来你就是我的人了博主主页 戳一戳 欢迎大佬指点 欢迎志同道合的朋友一起加油喔 目录 前言 一 面向对象的初步认知 1 什么是面向对象 2 面向对象和面向过程的区别 二 类和对象的基本概念 三 类和对象的定义和使用 1 类的创建 2 对象
  • 数据库的url配置8.0

    spring datasource username root spring datasource password lhh12345 spring datasource url jdbc mysql localhost 3306 myba
  • numpy.diag()结构及用法

    numpy diag v k 0 官方文档 以一维数组的形式返回方阵的对角线 或非对角线 元素 或将一维数组转换成方阵 非对角线元素为0 两种功能角色转变取决于输入的v 1 更深层的见numpy diagnal 参数详解 v array l
  • windows获取系统DPI

    dc GetDeviceCaps LOGPIXELSX 每英寸水平逻辑像素数 dc GetDeviceCaps LOGPIXELSY 每英寸垂直逻辑像素数 dc GetDeviceCaps HORZRES 水平像素总数 dc GetDevi
  • [Java]获取java方法注释实例

    Method methods company class getMethod getId null PK pk methods getAnnotation PK class System out println pk
  • vue指令中v-show和v-if以及keep-alive的区别

    v if 属于条件显示 满足条件就显示元素 不满足就删除元素 通过操作DOM元素完成 v if的首次渲染显示的开销较小 因为它只渲染满足条件的那一个元素 切换组件时 其开销较大 因为它每切换以此就要重新触发生命周期渲染显示新元素 v if值
  • JS实现轮播图(自动+手动)

    网页轮播图效果 核心原理 tips 代码在文章末尾 这个ul就是我们这四张图片的父盒子 我们通过对这个父盒子添加动画函数来实现移动 然后给父盒子来一个溢出隐藏就达到了轮播的效果 动画函数如下 function animate obj tar
  • 【python爬虫】8.温故而知新

    文章目录 前言 回顾前路 代码实现 体验代码 功能拆解 获取数据 解析提取数据 存储数据 程序实现与总结 前言 Hello又见面了 上一关我们学习了爬虫数据的存储 并成功将QQ音乐周杰伦歌曲信息的数据存储进了csv文件和excel文件 学到