新闻联播标题爬取练习

需求描述:

1.爬取时间段处于2000年到2021年的新闻联播标题
2.爬取格式为时间+标题字段

实现路径分析:

1.探查数据源,选择合适易爬取的网站。
①2016年到2021年时间段选择每日新闻联播
②2012到2015年时间段选择老官网
③2007到2009年时间段选择老老官网

暂未解决的问题

1.2009年6月28日到2012年1月1日之间的新闻找不到数据源,2002年10月1日前的新闻找不到数据源;
2.2007年以前的新闻都存在着网页跳转的问题①尝试常规解法,发现网页有加密,bs提取到的页面信息不全。又由于3秒内跳出网页因此②没法使用selenium模拟浏览器行为来爬取(时间太短)。

具体实现过程

①使用request和bs库爬取即可,使用openpyxl库来储存数据。

1
2
import requests,openpyxl
from bs4 import BeautifulSoup

②确定网址逻辑,观察发现,是以xxxxYxxMxxD的格式来构建的。因此用笨办法,构建年月日的列表如下,同时考虑到大小月的日数不同,构筑三个列表来区分。

1
2
3
4
5
6
7
8
9
Y=[2016,2017,2018,2019,2020,2021]#待爬取的年份
M=[1,2,3,4,5,6,7,8,9,10,11,12]#待爬取的月份
D1=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28]#非闰二月
D2=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]#小月
D3=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]#大月
lm=['02']#非闰小月28天
mm=['04','06','09','11']#中月3天
bm=['01','03','05','07','08','10','12']#大月31天
#列表组合循环生成网址

③生成每个网址url,elif虽然比较丑,但是胜在方便

1
2
3
4
5
6
7
8
W1="http://mrxwlb.com/"
W2="新闻联播文字版/amp/"
#网址的必备字段
for y in Y:
for m in M:
if m in lm:#判断 小月,中月,大月
for d in D1:
url=W1+str(y)+'年'+str(m)+"月"+str(d)+"日"+W2

④F12查看网页元素,确定新闻标题位置,确定目标字段位置为

find(“div”,class_=”cntn-wrp artl-cnt”).find_all(“li”)

书写储存代码如下

1
2
3
4
5
wb=openpyxl.Workbook()
sheet=wb.active
sheet.title='新闻采集(2016年-2021年)'
sheet['A1']='网址'
sheet['B1']='标题'

书写爬取代码如下

1
2
3
4
list_html=bs_html.find("div",class_="cntn-wrp artl-cnt").find_all("li")#定位字段                                
for title in list_html:
name=title.text
sheet.append([url,name])

⑤异常URL处理,由于每日新闻联播的网址会有一些很幼稚的错误,例如把网址里的新闻联播打错字成“新联联播”所以需要一个try,except判断防止程序中断,并且打印出有问题的网址,以供人工排查,代码如下:

1
2
3
4
5
6
7
8
try:
....#爬取网页的代码
except AttributeError:#打印异常值
print("WARNING!!!WARNING!!!WARNING!!!")
print('↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓这个url出错了↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓')
print(url)
print('↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑这个url出错了↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑')
print("WARNING!!!WARNING!!!WARNING!!!")

结尾:
1.至此,本次练习结束,爬取数据基本无误。
2.除了2012年与2013年的网页数据外,其他都可以用上述代码进行爬取,而2012年与2013年需要使用正则表达式来爬取,因此更改find方法为如下正则表达式即可:

1
2
pattern=re.compile("(?<=\(')(.+?)(?=',')")#正则表达式
result=pattern.findall(str(bs_html))

3.暂未解决前述环节提到的问题,欢迎交流指导。

完整代码见下,希望能帮助到你。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import requests,openpyxl
from bs4 import BeautifulSoup
Y=[2016,2017,2018,2019,2020,2021]#待爬取的年份
M=[1,2,3,4,5,6,7,8,9,10,11,12]#待爬取的月份
D1=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28]#非闰二月
D2=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]#小月
D3=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]#大月
lm=['02']#非闰小月28天
mm=['04','06','09','11']#中月3天
bm=['01','03','05','07','08','10','12']#大月31天
#列表组合循环生成网址

W1="http://mrxwlb.com/"
W2="新闻联播文字版/amp/"
#网址的必备字段

wb=openpyxl.Workbook()
sheet=wb.active
sheet.title='新闻采集(2016年-2021年)'
sheet['A1']='网址'
sheet['B1']='标题'
#创建表格储存数据

for y in Y:
for m in M:
if m in lm:#判断 小月
for d in D1:
url=W1+str(y)+'年'+str(m)+"月"+str(d)+"日"+W2
res_html=requests.get(url)
bs_html=BeautifulSoup(res_html.text,"html.parser")
try:
list_html=bs_html.find("div",class_="cntn-wrp artl-cnt").find_all("li")#定位字段
for title in list_html:
name=title.text
sheet.append([url,name])
#print(name)
except AttributeError:#打印异常值
print("WARNING!!!WARNING!!!WARNING!!!")
print(url)
print("WARNING!!!WARNING!!!WARNING!!!")
elif m in mm:#判断 中月
for d in D2:
url=W1+str(y)+'年'+str(m)+"月"+str(d)+"日"+W2
res_html=requests.get(url)
bs_html=BeautifulSoup(res_html.text,"html.parser")
try:
list_html=bs_html.find("div",class_="cntn-wrp artl-cnt").find_all("li")#定位字段
for title in list_html:
name=title.text
sheet.append([url,name])
#print(name)
except AttributeError:#打印异常值
print("WARNING!!!WARNING!!!WARNING!!!")
print(url)
print("WARNING!!!WARNING!!!WARNING!!!")
elif m in bm:#判断 大月
for d in D3:
url=W1+str(y)+'年'+str(m)+"月"+str(d)+"日"+W2
res_html=requests.get(url)
bs_html=BeautifulSoup(res_html.text,"html.parser")
try:
list_html=bs_html.find("div",class_="cntn-wrp artl-cnt").find_all("li")#定位字段
for title in list_html:
name=title.text
sheet.append([url,name])
#print(name)
except AttributeError:#打印异常值
print("WARNING!!!WARNING!!!WARNING!!!")
print(url)
print("WARNING!!!WARNING!!!WARNING!!!")

wb.save('D:\\新闻采集(2016年-2021年).xlsx')

最后,转载无需征得本人同意,但务必附上原址注明出处,感谢!