Python3,网站搭建之数据库表设计及数据存储!文末的彩蛋,我酸了~

举报
Carl_奕然 发表于 2023/08/29 13:57:01 2023/08/29
【摘要】 没想到,搭建网站,也是这么简单。

1. 爬取数据


有的小朋友会说,鱼叔,你这不是数据库表设计吗,怎么还送套餐是咋的?
哈哈~
买二送一…
我们爬取数据,是为了把数据直接存储到数据库中,这样就省下来造数据的过程~
我们今天爬取的内容,是这个网站

在这里插入图片描述

url = https://arxiv.org/list/cs/recent



这里汇集了外国各路大佬的大神级作品,而且还是免费的!
如果看不懂的话,可以谷歌翻译~!
我们看看这个网站长啥样子


老规矩,上代码

# -*- coding: utf-8 -*-
"""
@ auth : carl_DJ
@ time : 2023-08-25
"""

import requests
import csv
import traceback
from bs4 import BeautifulSoup
from PaperWeb.Servers.utils.requests import get_http_session

def gen_paper(skip):
    try:
        #url的skip设定参数,每次展示100条数据
        url = 'https://arxiv.org/list/cs/pastweek?skip={skip}&show=100'
        #设定headers
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'

        }
        #设定代理,如果未购买,则不需要填写,
        proxies  = {
            'http':"http://127.0.0.1:1092"
            'https':"http://127.0.0.1:1092"
        }
        #引用http代理池,避免资源被耗尽
        r = get_http_session().get(url,headers=headers,proxies=proxies)
        #不运用代理,则注释掉proxies=proxies
        #r = get_http_session().get(url,headers=headers)
        #判断返回状态
        if r.status_code !=200:
            return False,'请求网页失败'
        #使用lxml,是因为解析速度快
        soup = BeautifulSoup(r.text,'lxml')

        #获取论文url的信息
        all_dt = soup.find_all('dt')
        #获取论文的标题与作者
        all_dd = soup.find_all('dd')

        #使用zip方法,循环获取dd 和dt的内容,
        for  dt,dd in zip(all_dt,all_dd):
            #因为class是关键字,所以用_作区分,
            #获取url,通过class下的a标签的href链接来获取
            api_url = dt.find(class_ = 'list-identifier').find('a').get('href')
            root_url = 'https://arxiv.org'
            full_url = root_url + api_url

            """
            最开始使用contents,是直接获取到title的内容,text获取的内容很多,多而乱
            """

            #获取title,通过class标签下的contents获取,返回list
            title = dd.find(class_ = 'list-title mathjax').contents
            #对内容进行判断,如果titles的长度>=3,就截取第2部分
            if len(title) >=3:
                title = title[2]
            else:
                #text,返回的是str,
                title = dd.find(class_ = 'list-title mathjax').text

            #论文作者
            authors = dd.find(class_='descriptor').text
            #由于一行很多作者,所以要进行切分
            authors = authors.split(':')[1].replace('\n','')

            #生成器
            yield title,full_url,authors
    except Exception as e:
        #输出错误日志信息
        log(traceback.format_exc(),'error','gen_paper.log')
        error_str =  f'authors:[full_url:[{full_url},{authors}],title:[{title}'
        log(error_str,'error','gen_paper.log')
        # #打印错误
        # print(e)
        # traceback.print_exc()

def log(content,level,filepath):
    """

    :param content:输入错误信息内容
    :param level:错误等级
    :param filepath:路径
    :return:
    """
    if level =='error':
        with open(filepath,'a') as f:
            f.write(content)
    elif level =='fail':
        with open(filepath,'a') as f :
            f.write(content)

def run_main():
    '''
    保存到csv文件中
    :return:
    '''
    #定义一个空列表
    resl = []
    #循环所有的数据信息,一共有1273条论文,间隔100
    for i in range(0,1273,100):
        #这里的i 就是 skip,
        for full_url,title,authors in gen_paper(i):
            #添加到list中
            resl.append([title,full_url,authors])
            print(title,'done')

        #打开文件,进行保存
        with open('paper.csv','w') as f :
            #打开上面获取到的文件内容
            cw = csv.writer(f)
            #写数据到csv中
            for i in resl:
                #写一行
                cw.writerow(i)


if __name__ == '__main__':
    run_main()


这里不过多的对内容进行解析,不太明白的,可以看注释,
个人觉得,嗯~,虽然不是句句有注释,但是也没达到句句没有注释!
在不明白的,看小鱼这篇文章《Python3,多线程爬完B站UP主的视频弹幕及评论》这里面,能解释的,可都解释了!
瞅瞅,这就是运用到的代理

        #设定代理,如果未购买,则不需要填写
        proxies  = {
            'http':"http://127.0.0.1:1092"
            'https':"http://127.0.0.1:1092"
         }
        #引用http代理池,避免资源被耗尽,传入三个参数
         r = get_http_session().get(url,headers=headers,proxies=proxies)



代理是要花银子的,如果不是靠吃爬虫这碗饭的,或者不是发烧友,弄个免费的代理就行,虽然不稳定,但是,也行~
运行结果:

我为啥要把展示结果,
是因为要品一品,这爬取的结果,香不香。

2. 创建数据库


2.1 创建数据库表


一个是把创建的数据表,在pycharm的工程中写入
如下:
create.sql

--数据表

CREATE TABLE 'papers'(
    'id' int(11) NOT NULL AUTO_INCREMENT,
    'title' varchar(500) NOT NULL DEFAULT ''COMMIT '论文标题',
    'url' varchar(200) NOT NULL DEFAULT ''COMMIT '论文url',
    'authors' varchar(200) NOT NULL DEFAULT ''COMMIT '论文作者',
    'create_time' int(20) NOT NULL DEFAULT 0 COMMIT '创建时间',
    'update_time' int(20) NOT NULL DEFAULT 0 COMMIT '更新时间',
    'is_delete' tinyint(4) NOT NULL DEFAULT 0 COMMIT '是否删除',
    PRIMARY KEY ('id'),
    KEY 'title_IDX' ('title') USING BTREE,
    KEY 'authors_IDX' ('authors') USING BTREE
)ENGINE=InnoDB AUTO_INCREMENT =1 DEFAULT CHARSET=utf8 COMMIT='论文表'


这里展示的是MySQL的基本创建表的内容,不会的,可以看小鱼这篇《SQL基本用法一》
再看不懂的,就看看自己的银行卡余额,自己的左手及右手~
估计就会了!
写完之后,别忘了在数据库执行一下,不然怎么能生成表呢~

2.2 连接数据库


我们创建了数据库,就要通过pymysql把数据库连接起来,这样才能用起来~
继续上代码
mysql.py

# -*- coding: utf-8 -*-
"""
@ auth : carl_DJ
@ time : 2023-08-25
"""

import pymysql
import logging

'''
创建mysql数据库链接
'''

class MySQL(object):
    #创建数据库的基本链接信息
    def __init__(self,host='localhost',port = 3306,user='root',password = '123456',db='test'):
        #cursorclass = pymysql.cursors.DictCursor 数据库查询返回dict --> 默认返回值是 tuple
        self.conn = pymysql.connect(
            host = host,
            port = port,
            user=user,
            password=password,
            db=db,
            charset = 'utf8',
            cursorclass = pymysql.cursors.DictCursor
        )
        #定义logger
        self.log = logging.getLogger(__name__)

    def execute(self,sql,kwargs = None):
        # 创建mysql数据库链接
        try:
            #获取游标
            cursor = self.conn.cursor()
            #通过游标获取执行方法
            cursor.execute(sql,kwargs)
            #提交插入,删除等操作
            self.conn.commit()
            return cursor

        except Exception as e:
            #记录错误信息
            self.log.error(f'mysql execute eror:{e}',exc_info=True)
            raise e

    def query(self,sql,kwargs = None):
        #创建查询方法
        try:
            cursor = self.execute(sql,kwargs)

            if cursor:
                # 返回查询到的所有内容
                return cursor.fetchall()

            else:
                raise Exception(f'sql error:{sql}')
        except Exception as e:
            self.log.error(e)
            raise e
        finally:
            #关闭游标
            cursor.close()

    def insert(self,sql,kwargs = None):
        #数据插入
        try:
            cursor  = self.execute(sql,kwargs)
            if cursor:
                #获取最后行的id
                row_id = cursor.lastrowid
                return row_id
            else:
                raise Exception(f'sql error:{e}')
        except Exception as e:
            self.log.error(e)
            raise e
        finally:
            cursor.close()

    def escape_string(self,_):
        #对数据文件的内容进行转码,防止有一些特殊字符等
        return pymysql.escape_string(_)

db = MySQL(user='root',password='123456',db='papers')

这里用到的是pymysql这个库,不会使用的,看小鱼这篇文章《Python3链接Mysql数据库》

3. 数据存储


我们把爬取的数据,存储到数据库中。
同样,直接上代码

csv_to_mysql.py

# -*- coding: utf-8 -*-
"""
@ auth : carl_DJ
@ time : 2023-08-25
"""

import csv
import time
from PaperWeb.libs.mysql import db

def get_csv_info(path = 'paper.csv')
    #打开csv文件
    csvfile = open(path,'r')
    reader = csv.reader(csvfile)
    for item in reader:
        yield item

def get_insert_sql():
    #把数据插入到数据库
    items = []
    #获取时间
    _time = int(time.time())
    for item in get_csv_info():
        #对csv文件中的字符进行转码
        item = [db.escape_string(_) for _ in item]
        #添加到对应的list中,创建数据库时列表字段
        items.append(f"('{item[0]}',{item[1]},{item[2]},{_time},{_time})")
    #获取values值
    values = ','.join(items)

    #执行sql 语句的插入
    sql = f'''
        INSERT INTO 
         Paper ('title','url','authors','create_time','updata_time')
        Values
         {values}
    '''
    row_id = db.insert(sql)
    print(f'{row_id}条数据插入完成')

执行完之后,则就可以去数据库,看结果!
要是不完美,小鱼觉得那是不可能的~
要是完美,也不枉费小鱼肝到十二点的成果!

录完课 ,做总结,
喝点咖啡,溜溜娃,
娃睡了,我也开始肝代码。

4. 总结

这个网站搭建完成,小鱼接下来的目标有两个:

  • 1.会写一些python数据分析的博文;
  • 2.小鱼分享 自己四面阿里,终拿offer的经历及面试题。

哈哈,这提前剧透了~

为啥又要写 阿里面试的经历
因为,最近有小伙伴要准备阿里的面试,问了我一些关于阿里面试的问题,与其逐一的说,不如整理出来,share更多人!

这样小鱼我也省下更多的时间,做更多事情!!

好了,最后借用王二的一句话,结束今天的技术分享:

如果不是生活所迫,谁愿意才华一身!

我是小鱼

  • CSDN 博客专家;
  • 阿里云 专家博主;
  • 51CTO 博客专家;
  • 51认证讲师;
  • 认证金牌面试官;
  • 职场培训规划师;
  • 多个国内主流技术社区的认证专家博主;
  • 多款主流产品(阿里云等)测评一、二等奖获得者;


关注我,带你学习更多更有趣的Python知识。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。