爬虫目标
指定日期,爬取人民日报所有版面的新闻
简要分析版面链接分析
发现一共有20个版面,分别有 20 个链接,只是每个链接后的数字不同
http://paper.people.com.cn/rmrb/html/2020-03/12/nbs.D110000renmrb_01.htm
爬虫结构用到模块:requests、BeautifulSoup、gevent
构造参数类
需要下载其他日期,自行修改就好
class TOOL():
# 年月 yyyy-mm 格式
date = "2020-03"
# 日期
day = "12"
# 新闻详情页
text_url = "http://paper.people.com.cn/rmrb/html/{}/{}/".format(date,day)
# 版面 URL 列表
@classmethod
def get_urls(cls):
urls = list() # 链接列表
for num in range(1,20):
# 10 以下数字补 0
if 1 <= num < 10 :
num = "0" + str(num)
urls.append("http://paper.people.com.cn/rmrb/html/{}/{}/nbs.D110000renmrb_{}.htm".format(cls.date,cls.day,num))
return urls
获取新闻页链接
获取一个版面的新闻链接
def get_layout_url(url):
"""
返回值:[{"layout":layout,"href":href},{"layout":layout,"href":href},…]
"""
print(url)
r = requests.get(url=url)
r.encoding = r.apparent_encoding
# 解析网页获取 版面名称、文章链接
soup = BeautifulSoup(r.text ,"html.parser")
list_l_soup = soup.find(name="div",attrs={"class":"list_l"})
# 获取版面名
layout = list_l_soup.find_next(name="div",attrs={"class":"l_t"}).string.strip()
print(layout)
ul_soup = list_l_soup.find_next(name="div",attrs={"id":"titleList"}).find_next(name="ul")
li_soup = ul_soup.find_all(name="li")
# 返回值列表
href_titles = list()
for href_title_tag in li_soup:
# 获取 href
href = TOOL.text_url + href_title_tag.find(name="a")["href"]
print(href)
# 结果组合
href_titles.append({"layout":layout,"href":href})
return href_titles
下载新闻并保存
提前创建好rb/ 目录
def download(href_titles):
for href_title in href_titles:
# 获取新闻页
r = requests.get(url=href_title.get("href"))
r.encoding =r.apparent_encoding
# 解析新闻页
soup = BeautifulSoup(r.text ,"html.parser")
soup_text = soup.find(name="div",attrs={"class":"text_c"})
# 文章标题
title = soup_text.h1.string
print(title)
# 正文
main_sc= soup_text.find_next(name="div",attrs={"id":"ozoom"})
# 正文里有一段 script 的注释,对结果有影响,需要替换掉
main_sc.find_next(name="script",attrs={"language":"javascript"}).string = " "
main_text = main_sc.get_text().strip()
# 写入文件
with open("rb/"+title+".txt","w+",encoding="utf-8") as file:
file.write(main_text)
主逻辑if __name__ == '__main__':
# 通过for循环获取所有新闻链接,组成列表
href_titles = [get_layout_url(url) for url in TOOL.get_urls()]
# 添加协程队列并下载
layout_url_list = [gevent.spawn(download,href_title) for href_title in href_titles]
gevent.joinall(layout_url_list)