每日10行代码31:爬取人民日报一日的所有文章并存入数据库

今天又增加了存入数据库的功能,至此,爬取人民日报的项目已经结束,下一步我将跟另一篇文章的博主比较下代码,从他那学一些有用的东西。

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()

今日感悟:

  1. 写稍微大点程序就需要考虑异常处理的功能了,以免难得调试。比方说,程序里运用了20个函数,假如每个函数正常运行的概率是99%,那么程序正常运行的概率就是0.99的20次方,最终结果是0.8179,也就是最终概率是81.79%,也就是说出错的概率大概是18%,这也是一个很大的概率了,所以写程序时要力争把单个函数的正常运行率(含使用异常捕获)提高到99.99%,甚至更高。
  2. 如果程序运行时间比较长的话,需要在程序中加入程序运行进度的语句,就比如运行时间很长的程序显示一个进度条一样。

ps: 今日的10行代码又超时间了,后面几天有点忙,可能要少写点代码了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值