小言_互联网的博客

Python爬虫实战:爬取解放日报新闻文章

482人阅读  评论(0)

上一篇《Python 网络爬虫实战:爬取人民日报新闻文章》发布之后,确实帮到了不少朋友。

前几天,我好哥们问我:我想爬另一个日报新闻网站,网页结构几乎跟人民日报几乎一模一样,但是我用你的那个代码去爬却爬不下来数据呢?

顺着哥儿们发来的网址(网站传送地址:解放日报),我点进去看了一下,界面大概长这样。

跟人民日报的主页界面非常相似,都是 版面列表 -- 文章列表 -- 文章详情 的这种结构。

 本来我觉得肯定是我这哥儿们代码基础不过关,报的语法错误,先 “嘲讽” 他一波,然后帮他改好就得了。

没想到一分析,才发现这个网站的新闻数据,是 Ajax 动态加载出来的(具体区别就是,人民日报的数据是提前生成好在网页里,跟网页一起返回显示的;而解放日报则是分开的,先返回一个空网页,然后再通过数据的接口请求数据,把数据动态加载到空网页里显示)

虽然这个动态加载的爬虫也并不难,花了十来分钟就改完了,但是我感觉这还是蛮典型的一种类型的,所以趁这个机会拿来跟大家分享一下,遇到了这种类似的情况应该怎么做。

 

一、分析网站

其实第一步应该是 明确需求 的,就是要明确我们需要什么样的数据,希望以什么样的形式才保存等等。不过由于我们这个跟《人民日报》爬虫目标一致,所以需求部分就暂且略过了。

我们直接来分析网站。

1.1 数据动态加载是怎么回事儿

很多刚接触爬虫的同学,上来 F12 打开开发者工具,就咔咔定位数据找标签,如果是像人民日报那样的静态网页还好,你分析时看到的标签是什么样子,用代码爬的时候基本上也是那个样子;但是遇到解放日报这种动态加载的网站,就直接懵逼了,明明我标签位置,名字,class 和 id 什么的都没写错,为什么爬取的时候就总是报错说找不到标签呢?

答案就是,你找的那个标签是动态生成的,原始网页源码里根本没有,当然找不到了。

大家看下面,这是解放日报的版面导航列表。

一般大家爬取的时候,会先找到这个 <div class="dd-box"> 标签,然后在这个标签下找到所有的 <dd> 标签,然后再找 <a> 标签,然后就找到了想要的数据。

然鹅,当我们打开查看网页源码的时候(chrome 浏览器为例,鼠标右键,查看网页源代码),发现源代码里并没有我们需要的数据,而是一个类似于模板的东西。数据是通过后续动态的加载进来的。

当我们用爬虫去爬的时候,获取到的也是这样的源代码,当然取不到数据啦。

Tips1: 分析网页的时候,可以先查看一下网页源代码,看看自己需要的数据是否在里面,如果有,则可以继续接着分析,如果没有,说明数据是动态加载进来的,要换个思路。

 1.2 数据是怎么获取到的

既然网页源代码中找不到数据,那么我们去哪儿获得数据呢?

这就涉及到一个词,叫 “抓包” ,可能听上去很高深很难的样子,其实很简单的。我们知道数据肯定是通过发起 网络请求 获得的,就是网页向服务器发送一条请求,然后服务器把需要的数据回复回来,我们把网页向服务器发送的请求,和浏览器返回的数据,使用一些工具和手段截获下来进行分析,这个过程就是 “抓包”。

可能大家听着还是有点迷糊,下面我来具体演示一下。

打开开发者工具,切换到 Network,然后刷新网页(这里可以抓到网页加载过程中,向服务器发起的各种类型的请求)。

然后上图红框中圈出来的,就是我们抓取到的一条一条的请求包,有 js 脚本的,有 css 文件的,还有图片的等等各种类型的。我们要在这么多的 “请求包” 里找到包含我们需要的数据的包。

把列表里的这些请求从上到下一条一条的点开(在 Preview 里可以预览请求返回的数据),查看哪条请求是我们想要找的。

如上图箭头标识的请求点开以后,预览里的内容正好就是版面导航栏里的内容(预览里点击小箭头可以展开),我们成功找到了正确的请求。

也就是抓包成功!

1.3 抓到的包怎么用?

包含数据的请求包我们是抓到了,但是我们具体要怎么用呢?怎么把它用到爬虫程序里,通过它来爬数据呢?

还是那条请求,我们切换到 Headers 页签,可以查看到关于这条请求的一些基本信息。

主要关注几个部分 Request URL(请求链接),Request Method(请求方法),Query String Parameters(请求参数),(当然请求头的那些东西,User-Agent ,Cookie 什么的,按照实际情况该怎么加就怎么加)。

我们的目的就是,通过 python 代码模拟浏览器发出这条请求,直接获取服务器返回的数据(返回的数据就是前面预览里的那些)。


  
  1. import requests
  2. url = "https://www.shobserver.com/staticsg/data/journal/2021-04-24/navi.json?ver=1619268138175"
  3. r = requests.get(url)
  4. print(r.text)

 我们简单写几行代码模拟一下这个过程(url 就是上图中 Request URL 的内容,requests.get() 是因为 Request Method 是 GET)。

运行结果如下,可以成功获得数据。

1.4 怎么爬其他日期的数据

运行上面的代码,我们可以获得到 2021 年 4 月 24日的新闻数据,那我们如果想爬其他日期的新闻数据该怎么办呢?

这里我们观察一下请求的 url

https://www.shobserver.com/staticsg/data/journal/2021-04-24/navi.json?ver=1619268138175

其中有一段 2021-04-24 的字样,我们猜测,这个可能就是用来控制获取数据的日期的,改成别的日期 比如 2021-04-20 再试一下。

https://www.shobserver.com/staticsg/data/journal/2021-04-20/navi.json?ver=1619268138175

发现同样可以成功。

这样我们就知道,可以通过修改 url 里的日期字符串,来爬取指定日期的数据。

1.5 解析数据

该请求返回的数据,是 json 格式的字符串,我们需要用 json 库来进行解析。

(有同学可能想问了,那么一大串乱码似的文字,你怎么知道它是 json 格式的呢?简单来讲,看两个特点,一个是大括号 {} 包起来的,另一个是键值对格式,就是 xxx : xxx 这种形式的。实在不知道怎么判断的话,就去前面讲抓包的部分,看预览的地方,如果有小箭头能够折叠展开的,就是 json 格式)

我们可以看到 pages 里有版面的列表,每个版面的 articleList 里有文章列表,包含了我们需要的版面和文章列表信息。具体解析的 Python 代码这里就不讲了,文末会贴源码。

1.6 怎么爬文章详细内容

首先点开一个文章的正文页,用前面同样的分析方法过一遍,很容易知道,正文内容也是动态加载进来的,而且正文的数据是通过下面这条请求来获得到的。

我们简单写段代码来验证一下


  
  1. import requests
  2. url = "https://www.shobserver.com/staticsg/data/journal/2021-04-24/01/article/312840.json?ver=1619271661571"
  3. r = requests.get(url)
  4. print(r.text)

运行结果

经过对这条请求的 url 的分析,我们可以知道,/2021-04-24 是日期,/01 是指版面的编号,/312840 是文章的id。

https://www.shobserver.com/staticsg/data/journal/2021-04-24/01/article/312840.json?ver=1619271661571

 

至此,我们完成了对网站的分析,讲解了如何判断网站数据是动态加载还是静态加载,如果是动态加载的话如何抓包,抓包以后如何使用等等,并抓到了 新闻版面列表,文章列表,文章正文内容的请求接口。如果有哪里没有讲清楚,或者对以上内容有不太明白的地方,可以留言问我。

下面进行写代码,正式爬取。

 

二、编码环节

下面是爬虫源码,供大家学习交流使用,请勿用于非法用途。


  
  1. import requests
  2. import bs4
  3. import os
  4. import datetime
  5. import time
  6. import json
  7. def fetchUrl(url):
  8. '''
  9. 功能:访问 url 的网页,获取网页内容并返回
  10. 参数:目标网页的 url
  11. 返回:目标网页的 html 内容
  12. '''
  13. headers = {
  14. 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
  15. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
  16. }
  17. r = requests.get(url, headers=headers)
  18. r.raise_for_status()
  19. r.encoding = r.apparent_encoding
  20. return r.text
  21. def saveFile(content, path, filename):
  22. '''
  23. 功能:将文章内容 content 保存到本地文件中
  24. 参数:要保存的内容,路径,文件名
  25. '''
  26. # 如果没有该文件夹,则自动生成
  27. if not os.path.exists(path):
  28. os.makedirs(path)
  29. # 保存文件
  30. with open(path + filename, 'w', encoding= 'utf-8') as f:
  31. f.write(content)
  32. def download_jfrb(year, month, day, destdir):
  33. '''
  34. 功能:网站 某年 某月 某日 的新闻内容,并保存在 指定目录下
  35. 参数:年,月,日,文件保存的根目录
  36. '''
  37. url = 'https://www.shobserver.com/staticsg/data/journal/' + year + '-' + month + '-' + day + '/navi.json'
  38. html = fetchUrl(url)
  39. jsonObj = json.loads(html)
  40. for page in jsonObj[ "pages"]:
  41. pageName = page[ "pname"]
  42. pageNo = page[ "pnumber"]
  43. print(pageNo, pageName)
  44. for article in page[ "articleList"]:
  45. title = article[ "title"]
  46. subtitle = article[ "subtitle"]
  47. pid = article[ "id"]
  48. url = "https://www.shobserver.com/staticsg/data/journal/" + year + '-' + month + '-' + day + "/" + str(pageNo) + "/article/" + str(pid) + ".json"
  49. print(pid, title, subtitle)
  50. html = fetchUrl(url)
  51. cont = json.loads(html)[ "article"][ "content"]
  52. bsobj = bs4.BeautifulSoup(cont, 'html.parser')
  53. content = title + subtitle + bsobj.text
  54. print(content)
  55. path = destdir + '/' + year + month + day + '/' + str(pageNo) + " " + pageName + "/"
  56. fileName = year + month + day + '-' + pageNo + '-' + str(pid) + "-" + title + '.txt'
  57. saveFile(content, path, fileName)
  58. if __name__ == '__main__':
  59. '''
  60. 主函数:程序入口
  61. '''
  62. # 爬取指定日期的新闻
  63. newsDate = input( '请输入要爬取的日期(格式如 20210416 ):')
  64. year = newsDate[ 0: 4]
  65. month = newsDate[ 4: 6]
  66. day = newsDate[ 6: 8]
  67. download_jfrb(year, month, day, 'Data')
  68. print( "爬取完成:" + year + month + day)

以上是爬取单天的新闻文章的爬虫,如果希望爬取一段时间内的新闻文章数据,可以参照《Python 网络爬虫实战:爬取人民日报新闻文章》中的代码进行修改。

 

三、运行效果

运行程序,输入 20210424 以后,爬虫自动爬取了 2021年4月24日的新闻数据,并保存在 Data / 20210424 / 目录下。

新闻文章列表

 

新闻文章正文

 


如果文章中有哪里没有讲明白,或者讲解有误的地方,欢迎在评论区批评指正,或者扫描下面的二维码,加我微信,大家一起学习交流,共同进步。


转载:https://blog.csdn.net/wenxuhonghe/article/details/116096752
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场