确实鸽了好一阵子了。上学期初心血来潮想要写写博客,写完第一篇博客我才发现写一篇充实的博客是多么费时费力,但是我还是坚持每周一篇博客地写了两个多月,毕竟期初事情也不是很多。直到期中过后我才发现每周余出一篇博客的时间是多么奢侈——我能坚持每天写千字日记,也做不到每周出一篇有质量的博客。实然有些心灰意冷,也许以后工作了再也没有年轻时的热情了。世事难有始有终,世俗聒噪,初心难追。

最近这几个月确实是项目缠身,无力旁顾他事。前期做了一些算法部分的工作,后来因为代码需要python 2.x的环境,我又不愿意卸载python 3.6去安装Anaconda(都怪早些时候没有随大流,坚持用了这么久python 3.6,太多的难装的库、难配的环境过来了,再从头开始实在是于心不忍),所以我后来主要负责数据爬虫以及与负责前端的朋友合作一起搭后端。

事情做的比较杂我也不便于一一赘述,我主要挑比较精华的部分写这篇博客,就MBA智库百科词条爬虫与同花顺财经数据爬虫两部分分别编写。

(一)MBA智库百科词条爬虫

MBA智库,一个专注于经济管理领域的知识平台。对于财经专业的学生应该是一部挺有用的百科全书了?

首先明确爬虫的目标,我希望能够将MBA智库中的四十多万词条包括其具体百科内容全部存储到本地,数据的宗旨是取精去糟,层次清晰,不要拿到无关信息(就像上面这个页面,像广告与推荐各种无关信息)。

自顶而下的看这个爬虫,主要分为两个主要部分——宏观上如何确保拿到全部词条条目数据?微观上如何精确获取词条百科中的全部信息?下面我就这两个问题分别阐释:

1.1 宏观问题——如何确保拿到全部词条条目数据

一个非常直观的思路是使用病毒式BFS搜索的方式来获取这种百科全书式的数据。说句老实话,这个方法我至今没有成功在爬虫中运用过。主要有两个原因:

  1. 一个问题是BFS会造成极大的重复搜索,体现在爬虫中就是需要使用更多的访问次数,这将大大增加你为了避免被目标服务器封锁而产生的时间代价,而如果为了减少访问次数而选择比对已获取的信息,则会随着爬虫的推进查重成本越来越沉重;
  2. 另一个问题是网络框架的连通性未知,BFS无法确保遍历整个网络,一些边缘上的“幽灵”结点往往无法获取,而很多时候这种“幽灵”结点的数量是庞大的,即使他们的价值很低;

所以做事之前先观察,磨刀不误砍柴功。事实上MBA智库提供了一个索引目录?

显然所有的词条不可能只有索引页面上的这些数量。点击“企业管理”类别进去可以发现,每个类别索引分类下包含两种信息,第一种是该类别下的亚类,另一个是隶属该类的词条(从索引树状结构来说每个结点下有非叶结点与叶子结点)。经过我的观察发现,每一块索引词条(如上页面中的企业管理~责任中心,财务管理~职业理财师)被包含在一个<p>...</p>标签内,事实上每对<p>标签下的第一个子标签中的分类词条将包含后面所有词条(如企业管理与财务管理分别包含了它们后面的所有词条),例外有两个:

  1. 如果出现<p>标签的第一个子“其他”或者“其它”,则跳过这个<p>标签;

  2. 此时下一个<p>标签里所有的词条包含的集合都是互斥的(即其他条目中的所有词条包含的亚类互相交集为空);

写到这里请容许我吐槽一下MBA智库这糟糕的网站设计。事实上索引页面上所有的<p>标签都是平级的,用Beautifulsoup库的<tag>.next_sibling()方法可以一路next到底,也就是说最大的六大类——管理、经济、金融、法律、行业、综合六大百科之间都没有一个<div>标签把它们隔开,唯一能够分开这六大类的方法就是如果在next的过程中找到了<h2>标签,也许是新的一大类开始了罢。而这种性质延续到了词条百科的全部信息之中。其他一些糟糕的地方就是像“其他”和“其它”居然都存在于索引页面上,实在是设计前端的人太不走心了。

 def parse_categories(self,categories):                               # 以参数列表中的条目为根目录, 穿透根目录就完事了with open("{}/{}".format(self.date,self.categoryWait),"a") as f: # 将传入的所有类别记录到categoryWait.txt中for category in categories: f.write("{}\n".format(category)) for category in categories:with open("{}/{}".format(self.date,self.categoryDone),"a") as f: f.write("{}\n".format(category))             subCategories = list()                                      # 存储该category下的所有亚类entries = list()                                            # 存储该category下的所有条目html = self.session.get(self.categoryURL.format(category)).textcount = 0while True:flag = True                                                # flag用于判断是否还存在下一页count += 1soup = BeautifulSoup(html,"lxml")divs1 = soup.find_all("div",class_="CategoryTreeSection")# 子类超链接divs2 = soup.find_all("div",class_="page_ul")             # 条目超链接if divs1:for div in divs1:aLabel = div.find_all("a")for a in aLabel:if str(a.string)=="+": continue              # "+"号是一个特殊的书签超链接subCategories.append(str(a.string))if divs2:for div in divs2:aLabel = div.find_all("a")for a in aLabel:if a.attrs["title"][:6]=="Image:": entries.append("Image:{}".format(a.string))else: entries.append(str(a.string))string = "正在处理{}类别第{}页的信息 - 共{}个子类{}个条目...".format(category,count,len(subCategories),len(entries))print(string)with open("{}/{}".format(self.date,self.log),"a") as f:f.write("{}\t{}\n".format(string,time.strftime("%Y-%m-%d %H:%M:%S")))  buttons = soup.find_all("a",title="Category:{}".format(category))if buttons:                                               # 可能并没有这个按钮for button in buttons:if str(button.string)[0]=="后":nextURL = self.wikiURL + button.attrs["href"][1:]html = self.session.get(nextURL).text      # 进入下一页flag = False                                # flag高高挂起break                                         # 退出循环if flag: break                                            # flag为True无非两种情况: 没有button, 或者只要前200页的buttonstring = "开始获取{}类别下所有条目信息...".format(category)print(string)with open("{}/{}".format(self.date,self.log),"a") as f:f.write("{}\t{}\n".format(string,time.strftime("%Y-%m-%d %H:%M:%S")))self.parse_entries(entries,False)                            # 爬取当前类别的条目string = "开始获取{}类别下所有亚类信息...".format(category)print(string)with open("{}/{}".format(self.date,self.log),"a") as f:f.write("{}\t{}\n".format(string,time.strftime("%Y-%m-%d %H:%M:%S")))self.parse_categories(subCategories)                       # 爬取当前类别的亚类def parse_index_page(self,):                                         # 爬取MBA词条分类索引页面print("正在获取MBA索引页面信息...")html = self.session.get(self.indexURL).textsoup = BeautifulSoup(html,"lxml")h2s = soup.find_all("h2")                                      # 由于<div>标签过于混乱, 采用<h2>标签来定位不同分类categories = dict()for h2 in h2s:tempList = list()div = h2.find_parent().next_sibling.next_sibling           # 经验之谈, 没有为什么ps = div.find_all("p")                                      # <p>标签索引每行第一个类别for p in ps:a = p.find("a")                                            # 只要第一个<a>标签即可因为后面的都可以在第一个类别的亚类或者次亚类中寻找到if a: tempList.append(str(a.string))                  # 存在<a>标签则取第一个else:                                                   # 不存在<a>标签的情况比较复杂, 总的来说是MBAlib网页设计者实在是太垃圾了label = p.find_next_sibling("p")                     # 后续平行结点还有<p>标签定位label = label if label else p.find_next_sibling("dl")# 否则定位<dl>标签aLabel = label.find_all("a")                        # "其他/它"类别下的所有类别, 互相平行所以全都要for a in aLabel: tempList.append(str(a.string))breakcategories[str(h2.string)] = tempList                         # 考虑到未必需要全部词条,因此这里把根条目按照六类分别存入字典print("索引页面信息获取完毕!\n共有{}个大类,{}个根条目".format(len(categories.keys()),sum(len(value) for value in categories.values())))return categories

上面的代码分别是获取索引页面全部根条目的函数与递归获取全部词条条目数据的代码?

因为是从我写的类里面摘取出来的,单独肯定无法运行,全部代码我也许会放在这部分结尾罢。这边利用一个递归去遍历这棵索引树即可,实测一般来说不会有重复的词条出现。

1.2 微观问题——如何精确获取词条百科中的全部信息

这个问题可能是比较麻烦的一件事情了,因为百科词条页面的结构并不唯一,我这边整理出来的方法经过测试可以应对大部分的词条,但因为我暂时没有对全部词条完成测试,所以我并不确信我的方法是完全可行的。

简单谈一下我的思路,观察发现有两种词条——百科词条与图片词条,图片词条在宏观问题部分的代码里面回去到的字符串将以"Image:"开头,因此可以用这个特征区分出这两类词条。对于图片词条简单获取第一个<img>标签中的href属性链接,用"wb"写入图片文件即可。对于百科词条的思路还是一"p"到底,但是事实上这里面有很多细节性的问题,如果朋友您愿意自己先尝试一下的话可能会有所感触。很多事情都是看起来很容易,一做就到处都是问题。

下面这段代码即是我获取百科词条数据的方法?

 def parse_entries(self,entries,driver=False,cycle=100,minInterval=60,maxInterval=90,):                                                                   # 给定词条列表获取它们所有的信息      for entry in entries:if driver:self.webdriver.get(self.entryURL.format(entry))html = self.webdriver.page_sourceelse:html = self.session.get(self.entryURL.format(entry)).textself.entryCount += 1if self.entryCount%cycle==0:interval = random.uniform(minInterval,maxInterval)time.sleep(interval)print("获取到第{}个条目 - 暂停{}秒...".format(self.entryCount,interval))string = "正在获取条目{}...".format(entry)print(string)with open("{}/{}".format(self.date,self.log),"a") as f:f.write("{}\t{}\n".format(string,time.strftime("%Y-%m-%d %H:%M:%S")))soup = BeautifulSoup(html,"lxml")if entry[:6]=="Image:":                                        # 图片词条保存为图片img = soup.find("img")imageURL = self.wikiURL + img.attrs["src"][1:]byte = self.session.get(imageURL).textwith open("{}/{}/{}".format(self.date,self.imageFolder,entry[6:]),"wb") as f: f.write(byte)else:                                                       # 非图片词条处理相对麻烦for script in soup.find_all("script"): script.extract()  # 删除脚本p = soup.find("p")                                         # 从第一个<p>标签的前一个标签开始搞label = p if isinstance(p.previous_sibling,element.NavigableString) else p.previous_sibling  text = str()                                           # 最终text被写入文本while True:if isinstance(label,element.NavigableString):       # 下一个平行节点有可能是字符串, 那就扔了label = label.next_siblingcontinueif not label: break                                    # 没有下一个平行节点, 那就再见if "class" in label.attrs.keys() and \label.attrs["class"][0]=="printfooter": break    # 页脚处与空标签处暂停string = self.labelCompiler.sub("",str(label))text += "{}\n".format(string.strip())label = label.next_sibling_nCompiler = re.compile(r"\n+",re.S)text = _nCompiler.sub("\n",text)with open("{}/{}/{}.txt".format(self.date,self.entryFolder,entry),"a",encoding="UTF-8") as f:f.write(text)

最后贴上MBAlib类的代码?

#-*- coding:UTF-8 -*-
"""作者:囚生CY平台:CSDN时间:201/04/03转载请注明原作者创作不易,仅供分享
"""
import os
import re
import sys
import time
import numpy
import random
import pandas
import requestsfrom bs4 import BeautifulSoup,element
from selenium import webdriver
from multiprocessing import Processclass MBAlib():def __init__(self,userAgent="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",phantomPath="E:/Python/phantomjs-2.1.1-windows/bin/phantomjs.exe",driver=True, ):""" 设置类构造参数 """self.userAgent = userAgent                                       # 设置浏览器用户代理self.phantomPath = phantomPath""" 设置类常用参数 """self.workspace = os.getcwd()                                    # 获取当前工作目录self.date = time.strftime("%Y%m%d")                                # 获取类初始化的时间self.labelCompiler = re.compile(r"<[^>]+>",re.S)                # 标签正则编译self.entryCount = 0                                                # 记录已经爬取的条目数量self.mainURL = "https://www.mbalib.com/"                        # MBA首页URLself.wikiURL = "https://wiki.mbalib.com/"                      # MBA百科URLself.searchURL = self.mainURL + "s?q={}"                         # MBA搜索URLself.wikisearchURL = self.wikiURL + "wiki/Special:Search?search={}&fulltext=搜索"self.entryURL = self.wikiURL + "wiki/{}"                         # MBA条目URLself.indexURL = self.wikiURL + "wiki/MBA智库百科:分类索引"            # MBA词条分类索引页面URLself.categoryURL = self.wikiURL + "wiki/Category:{}"            # MBA词条类别页面URLself.session = requests.Session()                                # 类专用sessionself.myHeaders = {"User-Agent":self.userAgent}                   # 爬虫头信息self.imageFolder = "image"                                        # 存放图片词条的子文件夹self.entryFolder = "entry"                                      # 存放词条文本的子文件夹self.logFolder = "log"                                          # 存放程序运行的子文件夹self.log = "{}/log.txt".format(self.logFolder)                  # 记录文件self.categoryWait = "{}/categoriyWait.txt".format(self.logFolder)# 记录队列中所有的类别文件self.categoryDone = "{}/categoriyDone.txt".format(self.logFolder)# 记录已经获取完毕的类别文件if driver: self.webdriver = webdriver.Firefox()                     # 初始化火狐浏览器""" 初始化操作 """self.session.headers = self.myHeaders                             # 设置sessionself.session.get(self.mainURL)                                   # 定位主页if not os.path.exists("{}\\{}".format(self.workspace,self.date)):# 每个交易日使用一个单独的文件夹(用日期命名)存储金融数据print("正在新建文件夹以存储{}MBA智库的数据...".format(self.date))os.mkdir("{}\\{}".format(self.workspace,self.date))os.mkdir("{}\\{}\\{}".format(self.workspace,self.date,self.imageFolder))os.mkdir("{}\\{}\\{}".format(self.workspace,self.date,self.entryFolder))os.mkdir("{}\\{}\\{}".format(self.workspace,self.date,self.logFolder))def parse_entries(self,entries,driver=False,cycle=100,minInterval=60,maxInterval=90,):                                                                    # 给定词条列表获取它们所有的信息      for entry in entries:if driver:self.webdriver.get(self.entryURL.format(entry))html = self.webdriver.page_sourceelse:html = self.session.get(self.entryURL.format(entry)).textself.entryCount += 1if self.entryCount%cycle==0:interval = random.uniform(minInterval,maxInterval)time.sleep(interval)print("获取到第{}个条目 - 暂停{}秒...".format(self.entryCount,interval))string = "正在获取条目{}...".format(entry)print(string)with open("{}/{}".format(self.date,self.log),"a") as f:f.write("{}\t{}\n".format(string,time.strftime("%Y-%m-%d %H:%M:%S")))soup = BeautifulSoup(html,"lxml")if entry[:6]=="Image:":                                        # 图片词条保存为图片img = soup.find("img")imageURL = self.wikiURL + img.attrs["src"][1:]byte = self.session.get(imageURL).textwith open("{}/{}/{}".format(self.date,self.imageFolder,entry[6:]),"wb") as f: f.write(byte)else:                                                       # 非图片词条处理相对麻烦for script in soup.find_all("script"): script.extract()  # 删除脚本p = soup.find("p")                                         # 从第一个<p>标签的前一个标签开始搞label = p if isinstance(p.previous_sibling,element.NavigableString) else p.previous_sibling  text = str()                                           # 最终text被写入文本while True:if isinstance(label,element.NavigableString):       # 下一个平行节点有可能是字符串, 那就扔了label = label.next_siblingcontinueif not label: break                                    # 没有下一个平行节点, 那就再见if "class" in label.attrs.keys() and \label.attrs["class"][0]=="printfooter": break    # 页脚处与空标签处暂停string = self.labelCompiler.sub("",str(label))text += "{}\n".format(string.strip())label = label.next_sibling_nCompiler = re.compile(r"\n+",re.S)text = _nCompiler.sub("\n",text)with open("{}/{}/{}.txt".format(self.date,self.entryFolder,entry),"a",encoding="UTF-8") as f:f.write(text)def parse_categories(self,categories):                                 # 以参数列表中的条目为根目录, 穿透根目录就完事了with open("{}/{}".format(self.date,self.categoryWait),"a") as f: # 将传入的所有类别记录到categoryWait.txt中for category in categories: f.write("{}\n".format(category)) for category in categories:with open("{}/{}".format(self.date,self.categoryDone),"a") as f: f.write("{}\n".format(category))             subCategories = list()                                      # 存储该category下的所有亚类entries = list()                                            # 存储该category下的所有条目html = self.session.get(self.categoryURL.format(category)).textcount = 0while True:flag = True                                                # flag用于判断是否还存在下一页count += 1soup = BeautifulSoup(html,"lxml")divs1 = soup.find_all("div",class_="CategoryTreeSection")# 子类超链接divs2 = soup.find_all("div",class_="page_ul")             # 条目超链接if divs1:for div in divs1:aLabel = div.find_all("a")for a in aLabel:if str(a.string)=="+": continue              # "+"号是一个特殊的书签超链接subCategories.append(str(a.string))if divs2:for div in divs2:aLabel = div.find_all("a")for a in aLabel:if a.attrs["title"][:6]=="Image:": entries.append("Image:{}".format(a.string))else: entries.append(str(a.string))string = "正在处理{}类别第{}页的信息 - 共{}个子类{}个条目...".format(category,count,len(subCategories),len(entries))print(string)with open("{}/{}".format(self.date,self.log),"a") as f:f.write("{}\t{}\n".format(string,time.strftime("%Y-%m-%d %H:%M:%S")))  buttons = soup.find_all("a",title="Category:{}".format(category))if buttons:                                               # 可能并没有这个按钮for button in buttons:if str(button.string)[0]=="后":nextURL = self.wikiURL + button.attrs["href"][1:]html = self.session.get(nextURL).text      # 进入下一页flag = False                                # flag高高挂起break                                         # 退出循环if flag: break                                            # flag为True无非两种情况: 没有button, 或者只要前200页的buttonstring = "开始获取{}类别下所有条目信息...".format(category)print(string)with open("{}/{}".format(self.date,self.log),"a") as f:f.write("{}\t{}\n".format(string,time.strftime("%Y-%m-%d %H:%M:%S")))self.parse_entries(entries,False)                            # 爬取当前类别的条目string = "开始获取{}类别下所有亚类信息...".format(category)print(string)with open("{}/{}".format(self.date,self.log),"a") as f:f.write("{}\t{}\n".format(string,time.strftime("%Y-%m-%d %H:%M:%S")))self.parse_categories(subCategories)                       # 爬取当前类别的亚类def parse_index_page(self,):                                         # 爬取MBA词条分类索引页面print("正在获取MBA索引页面信息...")html = self.session.get(self.indexURL).textsoup = BeautifulSoup(html,"lxml")h2s = soup.find_all("h2")                                      # 由于<div>标签过于混乱, 采用<h2>标签来定位不同分类categories = dict()for h2 in h2s:tempList = list()div = h2.find_parent().next_sibling.next_sibling           # 经验之谈, 没有为什么ps = div.find_all("p")                                      # <p>标签索引每行第一个类别for p in ps:a = p.find("a")                                            # 只要第一个<a>标签即可因为后面的都可以在第一个类别的亚类或者次亚类中寻找到if a: tempList.append(str(a.string))                  # 存在<a>标签则取第一个else:                                                   # 不存在<a>标签的情况比较复杂, 总的来说是MBAlib网页设计者实在是太垃圾了label = p.find_next_sibling("p")                     # 后续平行结点还有<p>标签定位label = label if label else p.find_next_sibling("dl")# 否则定位<dl>标签aLabel = label.find_all("a")                        # "其他/它"类别下的所有类别, 互相平行所以全都要for a in aLabel: tempList.append(str(a.string))breakcategories[str(h2.string)] = tempList                         # 考虑到未必需要全部词条,因此这里把根条目按照六类分别存入字典print("索引页面信息获取完毕!\n共有{}个大类,{}个根条目".format(len(categories.keys()),sum(len(value) for value in categories.values())))return categories

1.3 小结

这部分的最后我说一下爬虫被封的问题:

  • 不设定间断,每秒大约2~3个条目,连续120个条目后被封;
  • 每50个条目间断uniform(15,45)秒,大约700个条目后被封;
  • 使用selenium的问题在于加载页面很慢,我起初以为是图片加载很耗时,但是在设置了selenium的config后似乎并没有改善多少,这个问题我暂时还没有解决;
  • 对于四十多万的词条来说即便平均以1个/秒的速度也要花上整整五天的时间,所以如何加快速度确实是个很大的问题;

这些问题可能还需要后续的思考与解决。

(二)同花顺财经数据爬虫

同花顺财经数据爬虫的起因是我寒假实习中的体悟,在私募投研实习的过程中我深刻的感知到财经数据的稀贵性。除了那些基础的财经数据外,还有很多特殊的数据无从获取。像WIND,CHOICE这类付费的数据库有时候也无法满足机构投资者的个性化数据需求。因此我认为数据积累是一件极其重要的事情。

其中一个途径就是从同花顺财经网上获取数据?

我目前编写了每日获取上面第一张图中“资金流向”与“技术选股”两个模块下全部数据,“资金流向”部分可以参考我的博客https://blog.csdn.net/CY19980216/article/details/86647597中的内容,因为其实还是有不少细节性的问题,我都在之前那篇博客里面一一点出了。“技术选股”模块基本上是类同的,我不再赘述。

然后我重点谈一下上面第二、三张图i问财搜索引擎的使用问题。i问财搜索引擎可以说是目前全网最智能的一个财经领域具有问答系统性质的搜索引擎了。一般来说搜索结果将会以一张或若干张表格的形式呈现。但是如果简单使用requests方法去访问你将会发现得到的html中一张表格都没有。我的解决方案仍然是使用selenium,就可以成功获取到第三张图上的所有表格。

这边我不再提供代码,原因有两个,一方面确实花了我一段时间写StraightFlush类,这个类写了千行以上的代码,我有点不舍得来分享;另一方面也是团队的隐私,我个人不能透露太多。但是我还是觉得爬虫尽量自己写,我认为一百个人可以写出一百个不同的爬虫,而且自己写的爬虫以后维护起来也方便得多。

(三)总结

忙里偷闲写了这篇博客,事情多少善始善终罢,愿看到这篇博客的你也能在前进的路上不忘初心,别让过去的自己看不起将来的你。

【项目总结】近期爬虫详解(MBA智库百科词条爬虫同花顺财经数据爬虫)相关推荐

  1. Python分布式爬虫详解(二)

    上一章Python分布式爬虫详解(一)简单的介绍了什么是分布式爬虫,废话不多说,本章开始从零搭建一个爬取电影天堂电影信息的分布式爬虫. 本章知识点: a.CrawlSpider爬取电影天堂动作片第一页 ...

  2. 用python写一个简单的爬虫_Python实现简易Web爬虫详解

    编辑推荐: 本文主要介绍了Python实现简易Web爬虫详解,希望对大家有帮助. 本文来自于脚本之家 ,由火龙果软件Alice编辑,推荐. 简介: 网络爬虫(又被称为网页蜘蛛),网络机器人,是一种按照 ...

  3. 用idea建立jsp项目_用idea创建maven项目,配置tomcat详解

    用idea创建maven项目,配置tomcat详解,电脑上得有jdk1.7,或者1.8,然后就是maven3.x吧,再有就是tomcat7以上 下面就直接开始看图啦: 这个我刚刚开始没注意细看,原来w ...

  4. Tomcat 项目代码上线步骤详解

    Tomcat 项目代码上线步骤详解 1.上线内容(JSP代码,图片,包文件(jar|war|ear)) 2.上线内容来源 a.开发人员提供(邮件形式).tar.gz 压缩包(包文件开发负责编译 编译命 ...

  5. Java开源项目Hibernate包作用详解

    Java开源项目Hibernate包作用详解 本文引自:http://hi.baidu.com/nick6610/blog/item/70b58afa0d0eab9259ee90f7.html Jav ...

  6. 项目log4j日志管理详解

    项目log4j日志管理详解 项目log4j日志管理详解 log4j日志系统在项目中重要性在这里就不再累述,我们在平时使用时如果没有特定要求,只需在log4j.properties文件中顶入输出级别就行 ...

  7. Android项目刮刮奖详解(二)

    Android项目刮刮奖详解(一) 前言 上期我们简单地实现了一个画板的功能,用户可以在上面乱写乱画,其实,刮刮奖也是如此,用户刮奖的时候也是乱写乱画的. 刮刮奖原理 一共有两层画布,底层画布存放中奖 ...

  8. Python爬虫详解:爬虫是什么,如何做爬虫?

    Python爬虫详解:爬虫是什么,如何做爬虫? 读前必看: 本篇文章为教学向文章,通俗易懂的语言难免有不合适的地方,请大佬自行退场 爬虫是什么? 去查网,你会看到这样的解释: 爬虫是一种按照一定的规则 ...

  9. python编写数据库连接工具_详解使用Python写一个向数据库填充数据的小工具(推荐)...

    一. 背景 公司又要做一个新项目,是一个合作型项目,我们公司出web展示服务,合作伙伴线下提供展示数据. 而且本次项目是数据统计展示为主要功能,并没有研发对应的数据接入接口,所有展示数据源均来自数据库 ...

最新文章

  1. 并行化-你的高并发大杀器
  2. centerandzoom 无效_百度地图 app 点击事件无效、不触发 解决方案
  3. ListView单选的实现总结(转)
  4. c++ standard library_什么是C/C++的标准库?
  5. 大工19春计算机文化基础在线测试1,大工19春《计算机文化基础》在线测试1(含答案)...
  6. 循序渐进PYTHON3(十三) --8-- DJANGO之ADMIN
  7. 嵌入式实时操作系统ucos-ii_「正点原子NANO STM32开发板资料连载」第三十六章 UCOSII 实验 1任务调度...
  8. “鸿蒙”系统的产生并不是为了手机?任正非透露实情...
  9. 2021年了,Redis复制原理你应该理解!
  10. nacos 服务日志_如何屏蔽Nacos日志输出?
  11. python模块搜索原则_python 从小白开始 - 模块,包以及路径搜索
  12. smtp发送邮件和pop3收取邮件
  13. 苹果应用 Windows 申请 普通证书 和Push 证书 Hbuilder 个推(2)
  14. c# 盖尔-沙普利算法的改进
  15. 【数据采集与数据清洗】课堂笔记
  16. js加载本地shp数据到地图上_地图服务矢量数据获取方法总结
  17. 【项目篇- 封面后目录前的核心内容、优势展示部分如何打磨?(超全图文总结建议)】创新创业竞赛项目计划书、新苗国创(大创)申报书
  18. 表格中复制粘贴到其他位置的数据会携带引号等不可见字符,该怎么处理?
  19. html5 特效 banner,精品配饰活动banner html5特效制作教程
  20. Oracle 技巧总结 (二):nvl() 函数

热门文章

  1. Spring源码深度解析(郝佳)-学习-Bean Id 获取
  2. java农产品查询系统_基于jsp的农产品溯源管理系统-JavaEE实现农产品溯源管理系统 - java项目源码...
  3. ijkplayer的时序与状态图分析
  4. TensorFlow和PyTorch迎来了“后浪”
  5. 支持中文全文搜索的wiki.js
  6. 齿轮箱数据集_电力机车齿轮箱样本监测数据.1docx
  7. 深入分析MVC、MVP、MVVM、VIPER
  8. python开发com组件_Python生成COM组件(原创)
  9. 源中瑞区块链电子证照—推动政务发展
  10. win10 关闭快速启动以及进入BIOS