sqlite3相关知识
-
Sqlite3并发读写最近项目中涉及到sqlite并发读写的问题,参考一些文档并结合自己的实践,对sqlite3并发问题总结了几点:sqlite3的锁及事务类型sqlite3总共有三种事务类型:BEGIN [DEFERRED /IMMEDIATE / EXCLUSIVE] TRANSCATION,五种锁,按锁的级别依次是:UNLOCKED /SHARED /RESERVERD /PENDING /EXCLUSIVE。当执行select即读操作时,需要获取到SHARED锁(共享锁),当执行insert/update/delete操作(即内存写操作时),需要进一步获取到RESERVERD锁(保留锁),当进行commit操作(即磁盘写操作时),需要进一步获取到EXCLUSIVE锁(排它锁)。对于RESERVERD锁,sqlite3保证同一时间只有一个连接可以获取到保留锁,也就是同一时间只有一个连接可以写数据库(内存),但是其它连接仍然可以获取SHARED锁,也就是其它连接仍然可以进行读操作(这里可以认为写操作只是对
-
sqlite3数据库单表转存mysql数据库 本代码属于单表转换,在开始转换之前,假设你已经对应sqlite3数据的某张表在mysql数据库中建立相同名称的表和列,这里假设表中的列为,colname1,colname2,colname3...<?php //设置php执行时间无限制 set_time_limit(0); //sqlite3 config //请注意sqlite3数据库使用sqlite方法去操作会报错 //提示是一个加密文件或者不是一个数据库 //这里使用PDO驱动来连接和查询sqlite3数据库 //将sqlite3数据库与该脚本页
-
让Python更加充分的使用Sqlite3我最近在涉及大量数据处理的项目中频繁使用 sqlite3。我最初的尝试根本不涉及任何数据库,所有的数据都将保存在内存中,包括字典查找、迭代和条件等查询。这很好,但可以放入内存的只有那么多,并且将数据从磁盘重新生成或加载到内存是一个繁琐又耗时的过程。 我决定试一试sqlite3。 因为只需打开与数据库的连接, 这样可以增加可处理的数据量,并将应用程序的加载时间减少到零。此外,我可以通过 SQL 查询替换很多Python逻辑语句。 让Python更加充分的使用Sqlite3 我想分享一些关于这次
-
python3+sqlite3+多线程爬取某网站文章之前有爬取过某网站内容,抓取该网站发表的文章内容并保存到数据库,最近又想学一些爬虫方面的知识,所以把之前写的内容翻出来写一写笔记。首先使用谷歌浏览器分析网页源码,因为该网站是并没有涉及什么js、css渲染等动态网页,所以爬取的过程相对简单。爬取了该网站的标题、作者、发表时间、评论数、第一张大图的url和内容,然后格式化数据并保存到sqlite3其过程的实现很简单,就是简单的URL抓包提取网页,然后使用了正则表达式来提取数据,然后进行一些错误的判断和改进,并没有使用到太高级的爬虫技巧,还在继续学习之中。源码如下:# -*-coding:utf-8-*-import urllib.requestimport reimport sqlite3import timeimport randomimport threadingimport urllib.errorimport sysimport socketimport
sqlite3相关课程
sqlite3相关教程
- 4.创建、迁移模型,并添加数据 构建数据模型,是搭建 Restful Web API 的基础。构建模型,相当于构建数据库结构,且无需繁琐的 SQL 语言,另一个好处是,即使切换不同的数据库引擎(mysql 、SQL Server、Oracle等),也无需重新构建。下方我们构建一个学生信息表,包含学生姓名、学生年龄和学号。# models.pyfrom django.db import modelsclass StudentsInfo(models.Model): ''' 学生信息模型 ''' # 以下为学生信息表中的各个字段,CharField、IntegerField声明了字段类型分别为字符串类型和整型,max_length规定了字段最大长度,verbose_name相当于给字段取了一个别名,将来在管理页面会显示这个别名,否则显示字段名。例如,如果设置了verbose_name,那么在管理页面中,s_name字段将一“学生姓名”显示出来,如果没有设置verbose_name,则直接显示“s_name”。verbose_name只是方便用户以后的使用,设置与否不影响内部数据的存储。 s_name = models.CharField(max_length=8, verbose_name='学生姓名') s_age = models.IntegerField(verbose_name='学生年龄') s_number = models.CharField(max_length=16, verbose_name='学号')终端中运行命令以迁移模型python manage.py makemigrationspython migrate向数据库中添加演示数据,这里我们可以使用 PyCharm 自带的 Database 工具来完成。由于我们使用的是sqlite3 作为数据库,添加数据时,可双击左侧文件目录中的 db.sqlite3 文件,而后在右侧 Database 工具中双击要操作的数据表(AppDemo_studentsmodel)。在打开的数据表中,填入要填充的数据即可:
- 1. 基于 Cookie 的自动登录 如果是想基于基本的 API 方式登录,我们会面临两大难点:手机验证码校验 ,如下图所示:起点网站登录手机发送验证码滑动验证码校验,如下图所示:起点网站登录滑动验证码绕过这些校验的方法超过了本教程的知识范围,故我们不再次详细讨论。好在起点网支持自动登录过程,也就是 Cookie 登录:起点网支持自动登录第一次手动登录起点,选择自动登录后,起点网站返回的 Cookie 信息就会保存至本地。下次再访问起点网时,通过请求带上该 Cookie 信息就能正确识别用户,实现自动登录过程。Cookie 存在本地,就存在被代码读取的可能。通常而言,我们来使用 Python 中的 browsercookie 库可以获取浏览器的 cookie,目前它只支持 Chrome 和 FireFox 两种浏览器。不过对于 Chrome 80.X 版本的浏览器,其中的 cookie 信息被加密了,我们无法按照早期的操作进行 cookie 读取。不过网上这个博客给出了一个解密 Cookie 的代码,我们拿过来简单改造下,做成一个辅助模块:# 参考文档:https://blog.csdn.net/u012552769/article/details/105001108import sqlite3import urllib3import osimport jsonimport sysimport base64from cryptography.hazmat.backends import default_backendfrom cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modesurllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)def dpapi_decrypt(encrypted): import ctypes import ctypes.wintypes class DATA_BLOB(ctypes.Structure): _fields_ = [('cbData', ctypes.wintypes.DWORD), ('pbData', ctypes.POINTER(ctypes.c_char))] p = ctypes.create_string_buffer(encrypted, len(encrypted)) blobin = DATA_BLOB(ctypes.sizeof(p), p) blobout = DATA_BLOB() retval = ctypes.windll.crypt32.CryptUnprotectData( ctypes.byref(blobin), None, None, None, None, 0, ctypes.byref(blobout)) if not retval: raise ctypes.WinError() result = ctypes.string_at(blobout.pbData, blobout.cbData) ctypes.windll.kernel32.LocalFree(blobout.pbData) return resultdef aes_decrypt(encrypted_txt): with open(os.path.join(os.environ['LOCALAPPDATA'], r"Google\Chrome\User Data\Local State"), encoding='utf-8', mode="r") as f: jsn = json.loads(str(f.readline())) encoded_key = jsn["os_crypt"]["encrypted_key"] encrypted_key = base64.b64decode(encoded_key.encode()) encrypted_key = encrypted_key[5:] key = dpapi_decrypt(encrypted_key) nonce = encrypted_txt[3:15] cipher = Cipher(algorithms.AES(key), None, backend=default_backend()) cipher.mode = modes.GCM(nonce) decryptor = cipher.decryptor() return decryptor.update(encrypted_txt[15:])def chrome_decrypt(encrypted_txt): if sys.platform == 'win32': try: if encrypted_txt[:4] == b'x01x00x00x00': decrypted_txt = dpapi_decrypt(encrypted_txt) return decrypted_txt.decode() elif encrypted_txt[:3] == b'v10': decrypted_txt = aes_decrypt(encrypted_txt) return decrypted_txt[:-16].decode() except WindowsError: return None else: raise WindowsErrordef get_cookies_from_chrome(domain, key_list): sql = f'SELECT name, encrypted_value as value FROM cookies where host_key like "%{domain}%"' filename = os.path.join(os.environ['USERPROFILE'], r'AppData\Local\Google\Chrome\User Data\default\Cookies') con = sqlite3.connect(filename) con.row_factory = sqlite3.Row cur = con.cursor() cur.execute(sql) cookie_dict = {} for row in cur: if row['value'] is not None: name = row['name'] value = chrome_decrypt(row['value']) if value is not None and name in key_list: cookie_dict[name] = value return cookie_dictTips:上述这段代码不用纠结细节,前面函数的主要是替 get_cookies_from_chrome() 函数服务的,而该函数的输入要搜索的网站以及提取相应网站 cookie 信息中的某个具体字段,返回相应的结果。本人 Python 3.8.2 安装的是 win32 版本,该段代码亲测有效。来看看起点中文网给读者生成的 cookie 数据,我们调用上面的获取 cookie 信息的代码来从中提取相应数据:起点的cookie信息print(get_cookies_from_chrome('qidian.com', '_csrfToken'))print(get_cookies_from_chrome('qidian.com', 'e1'))print(get_cookies_from_chrome('qidian.com', 'e2'))执行上述代码我们可以得到如下结果:PS C:\Users\spyinx> & "D:/Program Files (x86)/python3/python.exe" c:/Users/spyinx/Desktop/test_cookie.py{'_csrfToken': 'YJklLmhMNpEfuSmqZZGaK72D4sUVJty52gyKwXXX'}{'e1': '%7B%22pid%22%3A%22qd_p_qidian%22%2C%22eid%22%3A%22qd_A08%22%2C%22l1%22%3A1%7D'}{'e2': '%7B%22pid%22%3A%22qd_p_qidian%22%2C%22eid%22%3A%22qd_A10%22%2C%22l1%22%3A1%7D'}这说明我们通过前面的代码能争取获取到起点网保存在 Chrome 浏览器中的 cookie 信息。因此,前面的代码将作为我们读取起点用户登录 Cookie 的重要辅助模块。Tips:这个测试只能在装了 Chrome 浏览器的 Windows 系统上进行测试,或者是 Linux 的桌面版我们首先来创建一个起点爬虫:PS C:\Users\Administrator\Desktop> scrapy startproject qidian_spider接下里我们来看看要提取的我的书架的信息:我的书架书籍信息对应的 items.py 的内容如下:# https://docs.scrapy.org/en/latest/topics/items.htmlimport scrapyclass QidianSpiderItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() # 分组 category = scrapy.Field() # 小说名 name = scrapy.Field() # 最新章节 latest_chapter = scrapy.Field() # 作者 author = scrapy.Field() # 更新时间 update_time = scrapy.Field() # 阅读进度 progress_status = scrapy.Field()接下来,在爬虫部分需要请求该页面然后提取相应的数据,我们的爬虫代码如下:"""获取用户书架数据"""import jsonfrom urllib import parsefrom scrapy import Requestfrom scrapy.spiders import Spiderfrom .get_cookie import get_cookies_from_chromefrom ..items import QidianSpiderItemclass BookCaseSpider(Spider): name = "bookcase" # 构造函数 def __init__(self): # 最重要的就是这个获取起点的cookie数据了,这里保存了之前用户登录的cookie信息 self.cookie_dict = get_cookies_from_chrome( "qidian.com", ["_csrfToken", "e1", "e2", "newstatisticUUID", "ywguid", "ywkey"] ) def start_requests(self): url = "https://my.qidian.com/bookcase" # http请求时附加上cookie信息 yield Request(url=url, cookies=self.cookie_dict) def parse(self, response): item = QidianSpiderItem() books = response.xpath('//table[@id="shelfTable"]/tbody/tr') for book in books: category = book.xpath('td[@class="col2"]/span/b[1]/a[1]/text()').extract_first() name = book.xpath('td[@class="col2"]/span/b[1]/a[2]/text()').extract_first() latest_chapter = book.xpath('td[@class="col2"]/span/a/text()').extract_first() update_time = book.xpath('td[3]/text()').extract_first() author = book.xpath('td[@class="col4"]/a/text()').extract_first() progress_status = book.xpath('td[@class="col5"]/a/text()').extract_first() item['category'] = category item['name'] = name item['latest_chapter'] = latest_chapter item['update_time'] = update_time item['author'] = author item['progress_status'] = progress_status print(f'get item = {item}') yield item最重要的方法就是那个获取 cookie 信息的方法了,正是靠着这个 cookie,我们才能获取相应的用户书架的网页并提取相应的书籍信息。接下来,简单实现一个 item pipeline 用于保存书架上的书籍信息,该代码位于 scrapy/pipelines.py 文件中,默认的 pipelines 都写会在这里:# 源码位置:scrapy/pipelines.py# Define your item pipelines here## Don't forget to add your pipeline to the ITEM_PIPELINES setting# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.htmlimport json# useful for handling different item types with a single interfacefrom itemadapter import ItemAdapterclass QidianSpiderPipeline: def open_spider(self, spider): self.file = open("bookcase.json", 'w+', encoding='utf-8') def close_spider(self, spider): self.file.close() def process_item(self, item, spider): data = json.dumps(dict(item), ensure_ascii=False) self.file.write(f"{data}\n") return item最后别忘了在 settings.py 中添加这个 item pipeline:ITEM_PIPELINES = { 'qidian_spider.pipelines.QidianSpiderPipeline': 300,}我们运行下这个爬虫,看看是否能抓到我们想要的数据:PS C:\Users\Administrator\Desktop> scrapy crawl bookcase最后的结果如下:获取用户的书架上书籍信息这样,我们就成功实现了用户登录后的访问动作。接下来我们在这个基础上进一步扩展,实现清除书架上所有的书籍,类似于淘宝的一键清除购物车。
- 1. 创建第一个Django应用程序 在创建第一个 Django 应用程序之前,我们需要使用 pyenv 工具创建相应的虚拟环境,操作如下:新建一个统一的目录,用于存放 Django 工程代码:[root@server ~]# mkdir django-manual[root@server ~]# cd django-manual/进入虚拟环境,然后建立 django-manual 虚拟环境。一般而言每个 Django 工程会创建一个虚拟环境,这样避免各个 Python 项目之间发生包冲突。建立好虚拟环境之后,激活虚拟环境。操作如下:[root@server django-manual]# pyenv versions system* 3.8.1 (set by /root/.pyenv/version) 3.8.1/envs/env-3.8.1 env-3.8.1 # 新建django-manual虚拟环境[root@server django-manual]# pyenv virtualenv 3.8.1 django-manualLooking in links: /tmp/tmpllz1yd5eRequirement already satisfied: setuptools in /root/.pyenv/versions/3.8.1/envs/django-manual/lib/python3.8/site-packages (41.2.0)Requirement already satisfied: pip in /root/.pyenv/versions/3.8.1/envs/django-manual/lib/python3.8/site-packages (19.2.3)# 手动新建的虚拟环境[root@server django-manual]# pyenv activate django-manualpyenv-virtualenv: prompt changing will be removed from future release. configure `export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior.(django-manual) [root@server django-manual]#接下来,我们需要安装 Django 2.2.11 版本(提示: django 3.0 最近发布了,但是还处于初步完善阶段,所以本次介绍以 Django 2.2.11 版本为准):(django-manual) [root@server django-manual]# pip install django==2.2.11 -i https://pypi.tuna.tsinghua.edu.cn/simpleLooking in indexes: https://pypi.tuna.tsinghua.edu.cn/simpleCollecting django==2.2.11 Downloading https://pypi.tuna.tsinghua.edu.cn/packages/be/76/7ccbcf52366590ca76997ce7860308b257b79962a4e4fada5353f72d7be5/Django-2.2.11-py3-none-any.whl (7.5MB) |████████████████████████████████| 7.5MB 71kB/s Requirement already satisfied: sqlparse in /root/.pyenv/versions/3.8.1/envs/django-manual/lib/python3.8/site-packages (from django==2.2.11) (0.3.1)Requirement already satisfied: pytz in /root/.pyenv/versions/3.8.1/envs/django-manual/lib/python3.8/site-packages (from django==2.2.11) (2019.3)Installing collected packages: djangoSuccessfully installed django-2.2.11WARNING: You are using pip version 19.2.3, however version 20.0.2 is available.You should consider upgrading via the 'pip install --upgrade pip' command.(django-manual) [root@server django-manual]# python -c "import django; print(django.__version__)"2.2.11这样子,虚拟环境中就安装好了 Django 2.2.11。Django 提供 django-admin 命令来帮助我们创建项目和应用,我们只需要使用 django-admin 命令即可快速创建我们的第一个 Django 项目:(django-manual) [root@server django-manual]# django-admin startproject first_django_app(django-manual) [root@server django-manual]# (django-manual) [root@server django-manual]# tree ..└── first_django_app ├── first_django_app │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py2 directories, 5 filesTips:尽量在 Linux 平台上完成实验,在 Windows 下操作在安装 mysqlclient 模块是会稍微有些工作要做。Django 项目可以由多个应用(app)组成,每个应用是一个逻辑上划分,即将某一个功能模块划归到这个应用。创建一个应用使用 django-admin starapp 应用名即可:(django-manual) [root@server django-manual]# cd first_django_app/(django-manual) [root@server first_django_app]# django-admin startapp hello_app(django-manual) [root@server first_django_app]# tree ..├── first_django_app│ ├── __init__.py│ ├── settings.py│ ├── urls.py│ └── wsgi.py├── hello_app│ ├── admin.py│ ├── apps.py│ ├── __init__.py│ ├── migrations│ │ └── __init__.py│ ├── models.py│ ├── tests.py│ └── views.py└── manage.py3 directories, 12 files可以看到,在使用 django-admin 执行创建 hello_app 应用后,该命令给我们生成了 hello_app 以及若干代码文件。为了能让 Django 项目运行起来,我们需要调整下 settings.py 文件中的配置:# settings.py 中默认使用 sqlite3...DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }}...# 现在调整成 mysql 数据库,读者需要自行准备mysql服务DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django_manual', 'USER': 'store', 'PASSWORD': 'xxxxxxxxx', 'HOST': '180.76.152.113', 'PORT': '9000', }}有了数据库支持,还需要在 Django 那边安装 mysql 相关的模块包。通常安装的是 mysqlclient 模块:# 安装相应的依赖包(django-manual) [root@server first_django_app]# yum install mysql-devel -y(django-manual) [root@server first_django_app]# pip install mysqlclient -i https://pypi.tuna.tsinghua.edu.cn/simpleLooking in indexes: https://pypi.tuna.tsinghua.edu.cn/simpleCollecting mysqlclient Downloading https://pypi.tuna.tsinghua.edu.cn/packages/d0/97/7326248ac8d5049968bf4ec708a5d3d4806e412a42e74160d7f266a3e03a/mysqlclient-1.4.6.tar.gz (85kB) |████████████████████████████████| 92kB 22.2MB/s Installing collected packages: mysqlclient Running setup.py install for mysqlclient ... doneSuccessfully installed mysqlclient-1.4.6最后一件事情,在启动 Django 服务之前,必须要先创建数据库。Django 服务默认并不会帮我们创建好数据库,我们必须手工建好数据库,然后再启动 Django 服务:[root@server ~]# mysql -u store -pxxxxxxxxx -h 180.76.152.113 -P9000Welcome to the MariaDB monitor. Commands end with ; or \g.Your MySQL connection id is 37328Server version: 5.7.26 MySQL Community Server (GPL)Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MySQL [(none)]> CREATE DATABASE IF NOT EXISTS django_manual DEFAULT CHARSET utf8;Query OK, 1 row affected (0.00 sec)MySQL [(none)]> show databases;+--------------------+| Database |+--------------------+| information_schema || alarms || dashboard || django_manual || graph || mysql || performance_schema || sys || uic |+--------------------+15 rows in set (0.00 sec)MySQL [(none)]> exit;Bye# ---------------------------------------------------------------------------------------(django-manual) [root@server first_django_app]# python manage.py runserver 0.0.0.0:8888Watching for file changes with StatReloaderPerforming system checks...System check identified no issues (0 silenced).You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.Run 'python manage.py migrate' to apply them.March 13, 2020 - 07:29:06Django version 2.2.11, using settings 'first_django_app.settings'Starting development server at http://0.0.0.0:8888/Quit the server with CONTROL-C.在完成上述这些步骤后,基本的工程就搭建起来了。接下来我们从外面访问这个端口结果如下:第一次访问 django 服务这个是 Django 在配置中做的一个白名单机制,它有一个 ALLOWED_HOSTS 配置参数,它用来设置访问服务的白名单。如果想要允许任何主机访问,直接设置如下:(django-manual) [root@server first_django_app]# cat first_django_app/settings.py...DEBUG = TrueALLOWED_HOSTS = ['*']...另外,默认 setting.py 中的 DEBUG 参数为 True。正因为如此,请求报错才会有如此详细的提示。在正真上线部署时候,这个参数一定要关闭。如果我设置如下参数再次从外部请求该 Django 服务时,浏览器的输出结果如下图所示。可以看到,除了显示一个冷冰冰 400 错误,无任何提示。这样屏蔽错误信息,防止有人从错误结果中推断服务漏洞,达到渗透的目的。(django-manual) [root@server first_django_app]# cat first_django_app/settings.py...DEBUG = FalseALLOWED_HOSTS = ['127.0.0.1']...设置 Debug=False 的错误输出我们重新设置好 DEBUG 和 ALLOWED_HOSTS 参数后,再次请求 Django 服务,可以得到 Dajngo 内置的欢迎页面,提示我们服务已经正常启动和运行。正常访问 Django 服务现在,我们写一个最简单的 Hello, World 字符串输出到页面上。改动 first_django_app/first_django_app/url.py 文件,这个文件是所有 url 请求路由的入口,所有的映射关系都会先通过这里:(django-manual) [root@server first_django_app]# pwd/root/django-manual/first_django_app(django-manual) [root@server first_django_app]# cat first_django_app/urls.py """注释性文本,省略"""from django.contrib import adminfrom django.urls import path## 新导入模块from django.http import HttpResponse## 视图函数def hello_world(*args, **kwargs): return HttpResponse("Hello, world.", content_type="text/plain")urlpatterns = [ path('admin/', admin.site.urls), ####添加的url映射,由上面的hello_world()函数处理 path('hello/', hello_world),]再次启动 Django 服务,访问 8888 端口的 /hello/ 路径,可以看到页面出现 “Hello, world.” 这样的字符,说明我们的第一个 URL 接口完成。页面输出 Hello,World.
- Spring MVC 数据模型(下) Spring MVC 企业级应用开发经典框架
- TensorFlow 快速入门示例 TensorFlow 是最受欢迎的开源机器学习框架
- Kotlin 委托(属性代理) Kotlin 是安卓开发的官方语言
sqlite3相关搜索
-
s line
safari浏览器
samba
SAMP
samplerate
sandbox
sanitize
saper
sas
sass
save
smarty模板
smil
smtp
snapshot
snd
snmptrap
soap
soapclient
soap协议