今天又增加了存入数据库的功能,至此,爬取人民日报的项目已经结束,下一步我将跟另一篇文章的博主比较下代码,从他那学一些有用的东西。
import requests
import re
from bs4 import BeautifulSoup
from urllib.parse import urljoin
import pymysql
def get_html(html_url):
'''获取html文本'''
res = requests.get(html_url)
res.encoding = "utf-8" # 以utf-8的编码格式来解析网页
return res.text
def get_article_urls(layout_url):
bs = BeautifulSoup(get_html(layout_url), "html.parser")
ul = bs.find("ul", class_="news-list")
a = ul.find_all("a")
return [urljoin(layout_url, s['href']) for s in a]
def make_dly_first_url(date):
'''日期格式为:YYYY-MM-DD,如果小于10,十位补零'''
base_url = r'http://paper.people.com.cn/rmrb/html/'
first_url = "nbs.D110000renmrb_01.htm"
dly_url = base_url + date[:7] + '/' + date[-2:] + '/'
return dly_url + first_url
def get_layout_urls(dly_url):
bs = BeautifulSoup(get_html(dly_url), "html.parser")
a_list = bs.find_all(id="pageLink")
# print(a_list)
return [urljoin(dly_url,s['href']) for s in a_list]
def get_article(article_url):
'''从文章内容页获取文章所有信息'''
article = {}
article_html = get_html(article_url)
bs = BeautifulSoup(article_html, "html.parser")
# 获取标题
title_tab = bs.find("h1")
article['title'] = title_tab.text
# 获取引题
lead_title_tab = bs.find("h3")
article['lead_title'] = lead_title_tab.text
# 获取副标题
subtitle_tab = bs.find("h3")
article['subtitle'] = subtitle_tab.text
# 获取日期和版面
date_tab = bs.find(class_ = "date")
article['date'] = date_tab.text
# 获取作者
pat2 = r'<founder-author>\r\n(.*?)\r\n</founder-author>'
author = re.search(pat2, article_html)
article['author'] = author.group(1)
# 获取正文
pat = r'<!--enpcontent-->([\s\S]*?)<!--/enpcontent-->'
content = re.search(pat, article_html)
article['content'] = content.group(1)
return article
def get_dly_articles(date):
dly_url = make_dly_first_url(date)
layout_urls = get_layout_urls(dly_url)
articles = []
for layout_url in layout_urls:
article_urls = get_article_urls(layout_url)
for article_url in article_urls:
article = get_article(article_url)
articles.append(article)
return articles
def dict_to_insertsql(table_name,dict_data):
columns = ','.join(dict_data.keys())
values=''
for i in dict_data.values():
if isinstance(i,int):
values += f'{i},'
else:
values += f'"{i}",'
sql = f"insert into {table_name}({columns}) values ({values[:-1]})" # [:-1]是为了去掉末尾的逗号
return sql
dly_articles = get_dly_articles('2020-09-11')
db = pymysql.connect(host='localhost',user='root', password='root', port=3306, db='rmrb')
cursor = db.cursor()
count = 1
for i in dly_articles:
sql = dict_to_insertsql('article',i)
cursor.execute(sql)
print(f"正在把第{count}篇文章写入数据库")
count += 1
db.close()
今日感悟:
- 写稍微大点程序就需要考虑异常处理的功能了,以免难得调试。比方说,程序里运用了20个函数,假如每个函数正常运行的概率是99%,那么程序正常运行的概率就是0.99的20次方,最终结果是0.8179,也就是最终概率是81.79%,也就是说出错的概率大概是18%,这也是一个很大的概率了,所以写程序时要力争把单个函数的正常运行率(含使用异常捕获)提高到99.99%,甚至更高。
- 如果程序运行时间比较长的话,需要在程序中加入程序运行进度的语句,就比如运行时间很长的程序显示一个进度条一样。
ps: 今日的10行代码又超时间了,后面几天有点忙,可能要少写点代码了。