-
看到这篇文章个人写爬虫如何挣钱: https://www.yuanrenxue.com/crawler/earn-money-python-crawler.html除了,兼职抓数据挣钱(PS:这也算是体力活了吧 哈哈),还有哪些道道? 透** 哈哈
-
1.配置python3环境安装步骤:# 配置华为云欧拉镜像源wget http://mirrors.myhuaweicloud.com/repo/mirrors_source.sh && sh mirrors_source.sh # 安装必要的工具,用来编译python3yum groupinstall "Development tools" -yyum -y install zlib zlib-develyum -y install bzip2 bzip2-develyum -y install ncurses ncurses-develyum -y install readline readline-develyum -y install openssl openssl-develyum -y install openssl-staticyum -y install xz lzma xz-develyum -y install sqlite sqlite-develyum -y install gdbm gdbm-develyum -y install tk tk-develyum -y install libffi libffi-devel # 下载,解压python3的tgz包,也可以自行去python官网下一个# 推荐使用Python-3.6.X版本wget https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tgztar -zxvf Python-3.6.7.tgzcd Python-3.6.7 # 配置信息及编译安装,安装到/opt/Bigdata/python3目录下,也可以自行指定./configure --prefix=/opt/Bigdata/python3 --enable-shared CFLAGS=-fPICmake && make install #配置变量echo "/opt/Bigdata/python3/lib" >> /etc/ld.so.confldconfig ln -s /opt/Bigdata/python3/bin/python3 /usr/bin/python3ln -s /opt/Bigdata/python3/bin/pip3 /usr/bin/pip3 2.安装kafka-python#kafka-python安装:pip3 install kafka-pythonpip3 install gssapi 3.运行kafka-python#运行步骤:#在安装有mrs客户端的节点上,例如客户端安装在/opt/client下source /opt/client/bigdata_envkinit kafka用户,例如kinit admin,输入密码#执行python3脚本#脚本样例:#producer:from kafka import KafkaProducerproducer = KafkaProducer(bootstrap_servers=["broker_ip:21007"], security_protocol="SASL_PLAINTEXT", sasl_mechanism="GSSAPI", sasl_kerberos_service_name="kafka", sasl_kerberos_domain_name="hadoop.hadoop.com")for _ in range(100): response = producer.send("test-topic", b"testmessage") result = response.get(timeout=50) print(result) #consumer:from kafka import KafkaConsumer consumer = KafkaConsumer("test-topic", bootstrap_servers=["broker_ip:21007"], group_id="test-group", enable_auto_commit="true", security_protocol="SASL_PLAINTEXT", sasl_mechanism="GSSAPI", sasl_kerberos_service_name="kafka", sasl_kerberos_domain_name="hadoop.hadoop.com")for message in consumer: print(message)
-
毕业一年左右,然后没找到工作,又去培训python。目前还在待业中,请问各位有没有工作推荐或是会点python爬虫我能做些什么事挣点收入呢?
-
比例wheel,或者加入anaconda这种也行。
-
。一般来说,传入MongoDB的IP及端口即可,其中第一个参数为地址,第二个参数为端口(如果不给它传递参数,默认是27017): pymongoclient = pymongo.MongoClient(host=, port=)的第一个参数还可以直接传入MongoDB的连接字符串,它以开头,例如:的属性即可返回test数据库。当然,我们也可以这样指定:对象。 : , : , : , : }的方法即可**数据,代码如下:print(result)属性来唯一标识。如果没有显式指明该属性,MongoDB会自动产生一个类型的属性。方法会在执行后返回值。 : , : , : , : }student2 = { : , : , : , : }result = collection.insert([student1, student2])print(result)的集合:方法了。当然,继续使用也没有什么问题。官方推荐使用和方法来分别**单条记录和多条记录,示例如下: : , : , : , : }result = collection.insert_one(student)print(result)print(result.inserted_id)>ab0f15c2606f0c1cf6c5方法不同,这次返回的是对象,我们可以调用其属性获取。方法,我们可以将数据以列表形式传递,示例如下: : , : , : , : }student2 = { : , : , : , : }result = collection.insert_many([student1, student2])print(result)print(result.inserted_ids)>[ObjectId(), ObjectId()],调用属性可以获取**数据的列表。或方法进行查询,其中查询得到的是单个结果,则返回一个生成器对象。示例如下:: })print(type(result))print(result)为的数据,它的返回结果是字典类型,运行结果如下:{'_id': ObjectId('5932a80115c2606a59e8a049'), 'id': '20170202', 'name': 'Mike', 'age': 21, 'gender': 'male'}属性,这就是MongoDB在**过程中自动添加的。来查询,此时需要使用bson库里面的: bson.objectid ObjectIdresult = collection.find_one({: ObjectId()})print(result)。方法。例如,这里查找年龄为20的数据,示例如下:: })print(results) result results: print(result)>{: ObjectId(), : , : , : , : }{: ObjectId(), : , : , : , : }{: ObjectId(), : , : , : , : }类型,它相当于一个生成器,我们需要遍历取到所有的结果,其中每个结果都是字典类型。,意思是大于,键值为20。来指定正则匹配,代表以M开头的正则表达式。以M开头属性存在的类型为类型的属性中包含字符串https://docs.mongodb.com/manual/reference/operator/query/。方法。比如,统计所有数据条数:print(count): }).count()print(count)方法,并在其中传入排序的字段及升降序标志即可。示例如下:, pymongo.ASCENDING)print([result[] result results])指定升序。如果要降序排列,可以传入。方法偏移几个位置,比如偏移2,就忽略前两个元素,得到第三个及以后的元素:, pymongo.ASCENDING).skip()print([result[] result results])方法指定要取的结果个数,示例如下:, pymongo.ASCENDING).skip().limit()print([result[] result results])方法,原本会返回三个结果,加了限制后,会截取两个结果返回。 bson.objectid ObjectIdcollection.find({: {: ObjectId()}})。方法,指定更新的条件和更新后的数据即可。例如:: }student = collection.find_one(condition)student[] = result = collection.update(condition, student)print(result)为的数据的年龄:首先指定查询条件,然后将数据查询出来,修改年龄后调用方法将原条件和修改后的数据传入。代表执行成功,代表影响的数据条数。操作符对数据进行更新,代码如下:字典内存在的字段。如果原先还有其他字段,则不会更新,也不会删除。而如果不用的话,则会把之前的数据全部用字典替换;如果原本存在其他字段,则会被删除。方法其实也是官方不推荐使用的方法。这里也分为方法和方法,用法更加严格,它们的第二个参数需要使用类型操作符作为字典的键名,示例如下:: }student = collection.find_one(condition)student[] = result = collection.update_one(condition, {: student})print(result)print(result.matched_count, result.modified_count)方法,第二个参数不能再直接传入修改后的字典,而是需要使用这样的形式,其返回结果是类型。然后分别调用和属性,可以获得匹配的数据条数和影响的数据条数。> : {: }}result = collection.update_one(condition, {: {: }})print(result)print(result.matched_count, result.modified_count),也就是年龄加1,执行之后会将第一条符合条件的数据年龄加1。> 方法,则会将所有符合条件的数据都更新,示例如下:: {: }}result = collection.update_many(condition, {: {: }})print(result)print(result.matched_count, result.modified_count)> 方法指定删除的条件即可,此时符合条件的所有数据均会被删除。示例如下:: })print(result)和。示例如下:: })print(result)print(result.deleted_count)result = collection.delete_many({: {: }})print(result.deleted_count)>即删除第一条符合条件的数据,即删除所有符合条件的数据。它们的返回结果都是类型,可以调用属性获取删除的数据条数。、和,它们是查找后删除、替换和更新操作,其用法与上述方法基本一致。、和等。api.mongodb.com/python/current/api/pymongo/collection.html。api.mongodb.com/python/current/api/pymongo/。来源: Python操作MongoDB看这一篇就够了
-
黄渤首次导演的电影《一出好戏》自8月10日在全国上映,至今已有10天,其主演阵容强大,相信许多观众也都是冲着明星们去的。目前《一出好戏》在猫眼上已经获得近60万个评价,评分为8.2分,票房已破10亿。作者本人(汤小洋 )今天也走进了电影院,对这部电影做了亲身的观看,看完后的感觉是有些许失落的,本以为是喜剧片,结果发现笑点一般,从搞笑的角度来看,不如《西虹市首富》,影片更多的是反映人类本性的一部电影,不应当做喜剧片来看,影片中展现的人与人之间的关系倒是值得我们去深思。今天就跟着 汤老师 一起来揭秘影片《一出好戏》,看看“这出好戏”到底如何?我们将使用Python抓取猫眼近10万条评论数据,并对获取到的数据进行分析,看看观众对这部电影的评价究竟如何?整个数据分析的过程分为四步:获取数据处理数据存储数据数据可视化一、获取数据1. 简介本次获取的是猫眼APP的评论数据,如图所示:通过分析发现猫眼APP的评论数据接口为:http://m.maoyan.com/mmdb/comments/movie/1200486.json?_v_=yes&offset=0&startTime=2018-07-28%2022%3A25%3A03通过对评论数据进行分析,得到如下信息:返回的是json格式数据1200486表示电影的专属id;offset表示偏移量;startTime表示获取评论的起始时间,从该时间向前取数据,即获取最新的评论cmts表示评论,每次获取15条,offset偏移量是指每次获取评论时的起始索引,向后取15条hcmts表示热门评论前10条total表示总评论数2. 代码实现这里先定义一个函数,用来根据指定url获取数据,且只能获取到指定的日期向前获取到15条评论数据# coding=utf-8__author__ = '汤小洋'from urllib import requestimport jsonimport timefrom datetime import datetimefrom datetime import timedelta# 获取数据,根据url获取def get_data(url): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36' } req = request.Request(url, headers=headers) response = request.urlopen(req) if response.getcode() == 200: return response.read() return Noneif __name__ == '__main__': html = get_data('http://m.maoyan.com/mmdb/comments/movie/1200486.json?_v_=yes&offset=0&startTime=2018-07-28%2022%3A25%3A03') print(html)二、处理数据对获取的数据进行处理,转换为json# 处理数据def parse_data(html): data = json.loads(html)['cmts'] # 将str转换为json comments = [] for item in data: comment = { 'id': item['id'], 'nickName': item['nickName'], 'cityName': item['cityName'] if 'cityName' in item else '', # 处理cityName不存在的情况 'content': item['content'].replace('\n', ' ', 10), # 处理评论内容换行的情况 'score': item['score'], 'startTime': item['startTime'] } comments.append(comment) return commentsif __name__ == '__main__': html = get_data('http://m.maoyan.com/mmdb/comments/movie/1200486.json?_v_=yes&offset=0&startTime=2018-07-28%2022%3A25%3A03') comments = parse_data(html) print(comments)三、存储数据为了能够获取到所有评论数据,方法是:从当前时间开始,向前获取数据,根据url每次获取15条,然后得到末尾评论的时间,从该时间继续向前获取数据,直到影片上映日期(2018-08-10)为止,获取这之间的所有数据。# 存储数据,存储到文本文件def save_to_txt(): start_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 获取当前时间,从当前时间向前获取 end_time = '2018-08-10 00:00:00' while start_time > end_time: url = 'http://m.maoyan.com/mmdb/comments/movie/1203084.json?_v_=yes&offset=0&startTime=' + start_time.replace(' ', '%20') html = None ''' 问题:当请求过于频繁时,服务器会拒绝连接,实际上是服务器的反爬虫策略 解决:1.在每个请求间增加延时0.1秒,尽量减少请求被拒绝 2.如果被拒绝,则0.5秒后重试 ''' try: html = get_data(url) except Exception as e: time.sleep(0.5) html = get_data(url) else: time.sleep(0.1) comments = parse_data(html) print(comments) start_time = comments[14]['startTime'] # 获得末尾评论的时间 start_time = datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S') + timedelta(seconds=-1) # 转换为datetime类型,减1秒,避免获取到重复数据 start_time = datetime.strftime(start_time, '%Y-%m-%d %H:%M:%S') # 转换为str for item in comments: with open('comments.txt', 'a', encoding='utf-8') as f: f.write(str(item['id'])+','+item['nickName'] + ',' + item['cityName'] + ',' + item['content'] + ',' + str(item['score'])+ ',' + item['startTime'] + '\n')if __name__ == '__main__': # html = get_data('http://m.maoyan.com/mmdb/comments/movie/1200486.json?_v_=yes&offset=0&startTime=2018-07-28%2022%3A25%3A03') # comments = parse_data(html) # print(comments) save_to_txt()有两点需要说明:服务器一般都有反爬虫策略,当请求过于频繁时,服务器会拒绝部分连接,我这里是通过增加每个请求间延时来解决,只是一种简单的解决方案,还望各位看客理解包涵根据数据量的多少,抓取数据所需时间会有所不同,我抓取的是2018-8-19到2018-8-10(上映当天)之间的数据,大概花了2个小时,共抓取约9.2万条评论数据四、数据可视化这里使用的是pyecharts,pyecharts是一个用于生成Echarts图表的类库,便于在Python中根据数据生成可视化的图表。Echarts是百度开源的一个数据可视化JS库,主要用于数据可视化。参考:http://pyecharts.org/# 安装pyechartspip install pyechartspyecharts v0.3.2以后,pyecharts 将不再自带地图 js 文件。如用户需要用到地图图表,可自行安装对应的地图文件包。# 安装地图文件包pip install echarts-china-provinces-pypkg # 中国省、市、县、区地图pip install echarts-china-cities-pypkg pip install echarts-china-counties-pypkg pip install echarts-china-misc-pypkg pip install echarts-countries-pypkg # 全球国家地图pip install echarts-united-kingdom-pypkg1. 粉丝位置分布代码实现# 导入Style类,用于定义样式风格from pyecharts import Style# 导入Geo组件,用于生成地理坐标类图from pyecharts import Geoimport json# 导入Geo组件,用于生成柱状图from pyecharts import Bar# 导入Counter类,用于统计值出现的次数from collections import Counter# 数据可视化def render(): # 获取评论中所有城市 cities = [] with open('comments.txt', mode='r', encoding='utf-8') as f: rows = f.readlines() for row in rows: city = row.split(',')[2] if city != '': # 去掉城市名为空的值 cities.append(city) # 对城市数据和坐标文件中的地名进行处理 handle(cities) # 统计每个城市出现的次数 # data = [] # for city in set(cities): # data.append((city, cities.count(city))) data = Counter(cities).most_common() # 使用Counter类统计出现的次数,并转换为元组列表 # print(data) # 定义样式 style = Style( title_color='#fff', title_pos='center', width=1200, height=600, background_color='#404a59' ) # 根据城市数据生成地理坐标图 geo = Geo('《一出好戏》粉丝位置分布', '数据来源:猫眼-汤小洋采集', **style.init_style) attr, value = geo.cast(data) geo.add('', attr, value, visual_range=[0, 3500], visual_text_color='#fff', symbol_size=15, is_visualmap=True, is_piecewise=True, visual_split_number=10) geo.render('粉丝位置分布-地理坐标图.html') # 根据城市数据生成柱状图 data_top20 = Counter(cities).most_common(20) # 返回出现次数最多的20条 bar = Bar("《一出好戏》粉丝来源排行TOP20", "数据来源:猫眼-汤小洋采集", title_pos='center', width=1200, height=60) attr, value = bar.cast(data_top20) bar.add("", attr, value, is_visualmap=True, visual_range=[0, 3500], visual_text_color='#fff', is_more_utils=True, is_label_show=True) bar.render("粉丝来源排行-柱状图.html")出现的问题:报错:ValueError: No coordinate is specified for xxx(地名)原因:pyecharts的坐标文件中没有该地名,实际上是名称不一致导致的,如数据中地名为'达州',而坐标文件中为'达州市'坐标文件所在路径:项目/venv/lib/python3.6/site-packages/pyecharts/datasets/city_coordinates.json解决:修改坐标文件,在原位置下复制个同样的,然后修改下地名{ "达州市": [ 107.5, 31.22 ], "达州": [ 107.5, 31.22 ], }不过由于要修改的地名太多,上面的方法实在是麻烦,所以我定义了一个函数,用来处理地名数据找不到的问题# 处理地名数据,解决坐标文件中找不到地名的问题def handle(cities): # print(len(cities), len(set(cities))) # 获取坐标文件中所有地名 data = None with open( '/Users/wangbo/PycharmProjects/python-spider/venv/lib/python3.6/site-packages/pyecharts/datasets/city_coordinates.json', mode='r', encoding='utf-8') as f: data = json.loads(f.read()) # 将str转换为json # 循环判断处理 data_new = data.copy() # 拷贝所有地名数据 for city in set(cities): # 使用set去重 # 处理地名为空的数据 if city == '': while city in cities: cities.remove(city) count = 0 for k in data.keys(): count += 1 if k == city: break if k.startswith(city): # 处理简写的地名,如 达州市 简写为 达州 # print(k, city) data_new[city] = data[k] break if k.startswith(city[0:-1]) and len(city) >= 3: # 处理行政 变更的地名,如县改区 或 县改市等 data_new[city] = data[k] break # 处理不存在的地名 if count == len(data): while city in cities: cities.remove(city) # print(len(data), len(data_new)) # 写入覆盖坐标文件 with open( '/Users/wangbo/PycharmProjects/python-spider/venv/lib/python3.6/site-packages/pyecharts/datasets/city_coordinates.json', mode='w', encoding='utf-8') as f: f.write(json.dumps(data_new, ensure_ascii=False)) # 将json转换为str可视化结果:粉丝人群主要集中在沿海一带从上图可以看出,《一出好戏》的观影人群主要集中在沿海一带,这些地方经济相对发达,城市人口基数庞大,极多的荧幕数量和座位、极高密度的排片场次,让观众便捷观影,活跃的观众评论也多,自然也就成为票房的主要贡献者。粉丝来源排名前20的城市依次为:北京、深圳、上海、成都、武汉、广州、西安、郑州、重庆、南京、天津、沈阳、长沙、东莞、哈尔滨、青岛、杭州、合肥、大连、苏州电影消费是城市消费的一部分,从某种角度来看,可以作为考察一个城市购买力的指标。这些城市在近年的GDP排行中大都居上游,消费水平较高。2. 词云图jieba是一个基于Python的分词库,完美支持中文分词,功能强大pip install jiebaMatplotlib是一个Python的2D绘**,能够生成高质量的图形,可以快速生成绘图、直方图、功率谱、柱状图、误差图、散点图等pip install matplotlibwordcloud是一个基于Python的词云生成类库,可以生成词云图pip install wordcloud代码实现:# coding=utf-8__author__ = "汤小洋"# 导入jieba模块,用于中文分词import jieba# 导入matplotlib,用于生成2D图形import matplotlib.pyplot as plt# 导入wordcount,用于制作词云图from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator# 获取所有评论comments = []with open('comments.txt', mode='r', encoding='utf-8') as f: rows = f.readlines() for row in rows: comment = row.split(',')[3] if comment != '': comments.append(comment)# 设置分词comment_after_split = jieba.cut(str(comments), cut_all=False) # 非全模式分词,cut_all=falsewords = " ".join(comment_after_split) # 以空格进行拼接# print(words)# 设置屏蔽词stopwords = STOPWORDS.copy() stopwords.add("电影") stopwords.add("一部") stopwords.add("一个") stopwords.add("没有") stopwords.add("什么") stopwords.add("有点") stopwords.add("这部") stopwords.add("这个") stopwords.add("不是") stopwords.add("真的") stopwords.add("感觉") stopwords.add("觉得") stopwords.add("还是") stopwords.add("但是") stopwords.add("就是")# 导入背景图bg_image = plt.imread('bg.jpg')# 设置词云参数,参数分别表示:画布宽高、背景颜色、背景图形状、字体、屏蔽词、最大词的字体大小wc = WordCloud(width=1024, height=768, background_color='white', mask=bg_image, font_path='STKAITI.TTF', stopwords=stopwords, max_font_size=400, random_state=50)# 将分词后数据传入云图wc.generate_from_text(words) plt.imshow(wc) plt.axis('off') # 不显示坐标轴plt.show()# 保存结果到本地wc.to_file('词云图.jpg')可视化结果:总体评价很不错对评论数据进行分词后制作如下词云图:从词云图中可以看到:评论中多次出现“可以”、“好看”、“不错”等热词,说明观众对《一出好戏》的总体评价还是很不错的同时对该影片中“张艺兴”的“演技”也给予了很大的认可,我本人今天在观看后也有同感,让我们看到了不一样的张艺兴,实力演员对于初次“导演”电影的“黄渤”,能拍出这样的影片,粉丝们也是比较肯定的,同时其本身就是票房的保障至于剧情方面,“现实”、“喜剧”、“搞笑”、“故事”等词语,能看出这是一部反映现实的故事片,同时也兼具喜剧搞笑对于评论中出现的“一般”、“失望”等,这些粉丝或许是和我一样,本以为这是一部爆笑喜剧片,笑点应该会很多(毕竟在我们心中,黄渤、王宝强等就是笑星),没想到笑点并不很多,至少与期待的有差距,导致心里有落差的原因吧^_^3. 评分星级代码实现:# coding=utf-8__author__ = "汤小洋"# 导入Pie组件,用于生成饼图from pyecharts import Pie# 获取评论中所有评分rates = []with open('comments.txt', mode='r', encoding='utf-8') as f: rows = f.readlines() for row in rows: rates.append(row.split(',')[4])# print(rates)# 定义星级,并统计各星级评分数量attr = ["五星", "四星", "三星", "二星", "一星"] value = [ rates.count('5') + rates.count('4.5'), rates.count('4') + rates.count('3.5'), rates.count('3') + rates.count('2.5'), rates.count('2') + rates.count('1.5'), rates.count('1') + rates.count('0.5') ]# print(value)pie = Pie('《一出好戏》评分星级比例', title_pos='center', width=900) pie.add("7-17", attr, value, center=[75, 50], is_random=True, radius=[30, 75], rosetype='area', is_legend_show=False, is_label_show=True) pie.render('评分.html')可视化结果:四、五星级影评合计高达83%从图中可以看出,五星比例接近62%,四星比例为21%,两者合计高达83%,可见口碑还是相当不错的,一星占比不足6%《一出好戏》作为黄渤第一次执导的作品,在拍摄过程中导演渤哥对自己的要求也是很严格的,所以有这样的成绩,也是理所当然。附:今天看电影的票根 ^_^本文转自汤小洋博客51CTO博客,如需转载,请自行联系原作者。原文链接
-
作者|程哥前言:嗨,对Python感兴趣的华为云社区小伙伴们,可以看这里啦,如何让初级者也能学会Python,本文档主要包含八个部分来讲解分别是:Python安装、简单shell命令、数字和运算符、变量、决策、函数、类与对象、文件目录;欢迎技术交流,下方评论留言,觉得本文档不错可以给笔者点个赞,多谢!
-
我用api调用aksk进行认证的话有python相关的sdk吗?
-
很多AI、EI产品没有提供Python SDK,很不方便。
-
虽然有些人认为区块链是一个早晚会出现问题的解决方案,但是毫无疑问,这个创新技术是一个计算机技术上的奇迹。那么,究竟什么是区块链呢?区块链以比特币(Bitcoin)或其它加密货币按时间顺序公开地记录交易的数字账本。[color=rgb(46,46,46)]更通俗的说,它是一个公开的数据库,新的数据存储在被称之为区块(block)的容器中,并被添加到一个不可变的链(chain)中(因此被称为区块链(blockchain)),之前添加的数据也在该链中。对于比特币或其它加密货币来说,这些数据就是一组组交易,不过,也可以是其它任何类型的数据。区块链技术带来了全新的、完全数字化的货币,如比特币和莱特币(Litecoin),它们并不由任何中心机构管理。这给那些认为当今的银行系统是骗局并将最终走向失败的人带来了自由。区块链也革命性地改变了分布式计算的技术形式,如以太坊(Ethereum)就引入了一种有趣的概念:智能合约(smart contract)。在这篇文章中,我将用不到 50 行的 Python 2.x 代码实现一个简单的区块链,我把它叫做 SnakeCoin。不到 50 行代码的区块链我们首先将从定义我们的区块是什么开始。在区块链中,每个区块随同时间戳及可选的索引一同存储。在 SnakeCoin 中,我们会存储这两者。为了确保整个区块链的完整性,每个区块都会有一个自识别的哈希值。如在比特币中,每个区块的哈希是该块的索引、时间戳、数据和前一个区块的哈希值等数据的加密哈希值。这里提及的“数据”可以是任何你想要的数据。 [code]import hashlib as hasher class Block: def __init__(self, index, timestamp, data, previous_hash): self.index = index self.timestamp = timestamp self.data = data self.previous_hash = previous_hash self.hash = self.hash_block() def hash_block(self): sha = hasher.sha256() sha.update(str(self.index) + str(self.timestamp) + str(self.data) + str(self.previous_hash)) return sha.hexdigest() [/code]真棒,现在我们有了区块的结构了,不过我们需要创建的是一个区块链。我们需要把区块添加到一个实际的链中。如我们之前提到过的,每个区块都需要前一个区块的信息。但问题是,该区块链中的第一个区块在哪里?好吧,这个第一个区块,也称之为创世区块,是一个特别的区块。在很多情况下,它是手工添加的,或通过独特的逻辑添加的。我们将创建一个函数来简单地返回一个创世区块解决这个问题。这个区块的索引为 0 ,其包含一些任意的数据值,其“前一哈希值”参数也是任意值。 [code]import datetime as date def create_genesis_block(): # Manually construct a block with # index zero and arbitrary previous hash return Block(0, date.datetime.now(), "Genesis Block", "0") [/code]这就是主要的部分。现在我们能创建自己的区块链了!在这里,这个区块链是一个简单的 Python 列表。其第一个的元素是我们的创世区块,我们会添加后继区块。因为 SnakeCoin 是一个极小的区块链,我们仅仅添加了 20 个区块。我们通过循环来完成它。[indent]# Create the blockchain and add the genesis block blockchain = [create_genesis_block()] previous_block = blockchain[0] # How many blocks should we add to the chain # after the genesis block num_of_blocks_to_add = 20 # Add blocks to the chain for i in range(0, num_of_blocks_to_add): block_to_add = next_block(previous_block) blockchain.append(block_to_add) previous_block = block_to_add # Tell everyone about it! print "Block #{} has been added to the blockchain!".format(block_to_add.index) print "Hash: {}n".format(block_to_add.hash) [/indent]让我们看看我们的成果:13757别担心,它将一直添加到 20 个区块 很好,我们的区块链可以工作了。如果你想要在主控台查看更多的信息,你可以编辑其完整的源代码并输出每个区块的时间戳或数据。这就是 SnakeCoin 所具有的功能。要使 SnakeCoin 达到现今的产品级的区块链的高度,我们需要添加更多的功能,如服务器层,以在多台机器上跟踪链的改变,并通过工作量证明算法(POW)来限制给定时间周期内可以添加的区块数量。 让这个极小区块链稍微变大些这个极小的区块链及其简单,自然也相对容易完成。但是因其简单也带来了一些缺陷。首先,SnakeCoin 仅能运行在单一的一台机器上,所以它相距分布式甚远,更别提去中心化了。其次,区块添加到区块链中的速度同在主机上创建一个 Python 对象并添加到列表中一样快。在我们的这个简单的区块链中,这不是问题,但是如果我们想让 SnakeCoin 成为一个实际的加密货币,我们就需要控制在给定时间内能创建的区块(和币)的数量。从现在开始,SnakeCoin 中的“数据”将是交易数据,每个区块的“数据”字段都将是一些交易信息的列表。接着我们来定义“交易”。每个“交易”是一个 JSON 对象,其记录了币的发送者、接收者和转移的 SnakeCoin 数量。注:交易信息是 JSON 格式,原因我很快就会说明。 [indent]{ "from": "71238uqirbfh894-random-public-key-a-alkjdflakjfewn204ij", "to": "93j4ivnqiopvh43-random-public-key-b-qjrgvnoeirbnferinfo", "amount": 3 } 现在我们知道了交易信息看起来的样子了,我们需要一个办法来将其加到我们的区块链网络中的一台计算机(称之为节点)中。要做这个事情,我们会创建一个简单的 HTTP 服务器,以便每个用户都可以让我们的节点知道发生了新的交易。节点可以接受 POST 请求,请求数据为如上的交易信息。这就是为什么交易信息是 JSON 格式的:我们需要它们可以放在请求信息中传递给服务器。[/indent][code]$ pip install flask # 首先安装 Web 服务器框架 [/code][code]from flask import Flask from flask import request node = Flask(__name__) # Store the transactions that # this node has in a list this_nodes_transactions = [] @node.route(´/txion´, methods=[´POST´]) def transaction(): if request.method == ´POST´: # On each new POST request, # we extract the transaction data new_txion = request.get_json() # Then we add the transaction to our list this_nodes_transactions.append(new_txion) # Because the transaction was successfully # submitted, we log it to our console print "New transaction" print "FROM: {}".format(new_txion[´from´]) print "TO: {}".format(new_txion[´to´]) print "AMOUNT: {}\n".format(new_txion[´amount´]) # Then we let the client know it worked out return "Transaction submission successful\n" node.run() [/code]真棒!现在我们有了一种保存用户彼此发送 SnakeCoin 的记录的方式。这就是为什么人们将区块链称之为公共的、分布式账本:所有的交易信息存储给所有人看,并被存储在该网络的每个节点上。但是,有个问题:人们从哪里得到 SnakeCoin 呢?现在还没有办法得到,还没有一个称之为 SnakeCoin 这样的东西,因为我们还没有创建和分发任何一个币。要创建新的币,人们需要“挖”一个新的 SnakeCoin 区块。当他们成功地挖到了新区块,就会创建出一个新的 SnakeCoin ,并奖励给挖出该区块的人(矿工)。一旦挖矿的矿工将 SnakeCoin 发送给别人,这个币就流通起来了。我们不想让挖新的 SnakeCoin 区块太容易,因为这将导致 SnakeCoin 太多了,其价值就变低了;同样,我们也不想让它变得太难,因为如果没有足够的币供每个人使用,它们对于我们来说就太昂贵了。为了控制挖新的 SnakeCoin 区块的难度,我们会实现一个工作量证明(Proof-of-Work)(PoW)算法。工作量证明基本上就是一个生成某个项目比较难,但是容易验证(其正确性)的算法。这个项目被称之为“证明”,听起来就像是它证明了计算机执行了特定的工作量。在 SnakeCoin 中,我们创建了一个简单的 PoW 算法。要创建一个新区块,矿工的计算机需要递增一个数字,当该数字能被 9 (“SnakeCoin” 这个单词的字母数)整除时,这就是最后这个区块的证明数字,就会挖出一个新的 SnakeCoin 区块,而该矿工就会得到一个新的 SnakeCoin。 [code]# ...blockchain # ...Block class definition miner_address = "q3nf394hjg-random-miner-address-34nf3i4nflkn3oi" def proof_of_work(last_proof): # Create a variable that we will use to find # our next proof of work incrementor = last_proof + 1 # Keep incrementing the incrementor until # it´s equal to a number divisible by 9 # and the proof of work of the previous # block in the chain while not (incrementor % 9 == 0 and incrementor % last_proof == 0): incrementor += 1 # Once that number is found, # we can return it as a proof # of our work return incrementor @node.route(´/mine´, methods = [´GET´]) def mine(): # Get the last proof of work last_block = blockchain[len(blockchain) - 1] last_proof = last_block.data[´proof-of-work´] # Find the proof of work for # the current block being mined # Note: The program will hang here until a new # proof of work is found proof = proof_of_work(last_proof) # Once we find a valid proof of work, # we know we can mine a block so # we reward the miner by adding a transaction this_nodes_transactions.append( { "from": "network", "to": miner_address, "amount": 1 } ) # Now we can gather the data needed # to create the new block new_block_data = { "proof-of-work": proof, "transactions": list(this_nodes_transactions) } new_block_index = last_block.index + 1 new_block_timestamp = this_timestamp = date.datetime.now() last_block_hash = last_block.hash # Empty transaction list this_nodes_transactions[:] = [] # Now create the # new block! mined_block = Block( new_block_index, new_block_timestamp, new_block_data, last_block_hash ) blockchain.append(mined_block) # Let the client know we mined a block return json.dumps({ "index": new_block_index, "timestamp": str(new_block_timestamp), "data": new_block_data, "hash": last_block_hash }) + "\n" [/code]现在,我们能控制特定的时间段内挖到的区块数量,并且我们给了网络中的人新的币,让他们彼此发送。但是如我们说的,我们只是在一台计算机上做的。如果区块链是去中心化的,我们怎样才能确保每个节点都有相同的链呢?要做到这一点,我们会使每个节点都广播其(保存的)链的版本,并允许它们接受其它节点的链。然后,每个节点会校验其它节点的链,以便网络中每个节点都能够达成最终的链的共识。这称之为共识算法(consensus algorithm)。我们的共识算法很简单:如果一个节点的链与其它的节点的不同(例如有冲突),那么最长的链保留,更短的链会被删除。如果我们网络上的链没有了冲突,那么就可以继续了。[indent]@node.route(´/blocks´, methods=[´GET´]) def get_blocks(): chain_to_send = blockchain # Convert our blocks into dictionaries # so we can send them as json objects later for block in chain_to_send: block_index = str(block.index) block_timestamp = str(block.timestamp) block_data = str(block.data) block_hash = block.hash block = { "index": block_index, "timestamp": block_timestamp, "data": block_data, "hash": block_hash } # Send our chain to whomever requested it chain_to_send = json.dumps(chain_to_send) return chain_to_send def find_new_chains(): # Get the blockchains of every # other node other_chains = [] for node_url in peer_nodes: # Get their chains using a GET request block = requests.get(node_url + "/blocks").content # Convert the JSON object to a Python dictionary block = json.loads(block) # Add it to our list other_chains.append(block) return other_chains def consensus(): # Get the blocks from other nodes other_chains = find_new_chains() # If our chain isn´t longest, # then we store the longest chain longest_chain = blockchain for chain in other_chains: if len(longest_chain) len(chain): longest_chain = chain # If the longest chain wasn´t ours, # then we set our chain to the longest blockchain = longest_chain [/indent]我们差不多就要完成了。在运行了完整的 SnakeCoin 服务器代码之后,在你的终端可以运行如下代码。(假设你已经安装了 cCUL)。1、创建交易[code]curl "localhost:5000/txion" \ -H "Content-Type: application/json" \ -d ´{"from": "akjflw", "to":"fjlakdj", "amount": 3}´ [/code]2、挖一个新区块 [code]curl localhost:5000/mine[/code]3、 查看结果。从客户端窗口,我们可以看到。 对代码做下美化处理,我们看到挖矿后我们得到的新区块的信息:[code]{ "index": 2, "data": { "transactions": [ { "to": "fjlakdj", "amount": 3, "from": "akjflw" }, { "to": "q3nf394hjg-random-miner-address-34nf3i4nflkn3oi", "amount": 1, "from": "network" } ], "proof-of-work": 36 }, "hash": "151edd3ef6af2e7eb8272245cb8ea91b4ecfc3e60af22d8518ef0bba8b4a6b18", "timestamp": "2017-07-23 11:23:10.140996" } [/code]大功告成!现在 SnakeCoin 可以运行在多个机器上,从而创建了一个网络,而且真实的 SnakeCoin 也能被挖到了。你可以根据你的喜好去修改 SnakeCoin 服务器代码,并问各种问题了。
-
2017年末,Python软件基金会与JetBrains网站一起开展了Python开发人员调查,目的是确定最新趋势,并深入了解Python开发世界今日的样子。 根据结果显示,每5个Python开发人员就有4个将Python作为第一编程语言,所有使用Python作为其主要语言的开发人员中又有一半在使用JavaScript。使用Python作为辅助编程语言的开发人员更喜欢将其与JavaScript(46%),C / C ++(42%),Java(41%)和C#(24%)一起使用。 Web开发人员与数据科学家:谁在统治Python世界? “你用Python做什么?”这个问题的答案非常有趣。 事实证明,数据分析和web开发是最广泛的用途。 13703 1、使用Python进行数据分析和机器学习的占24%; 2、使用Python进行数据分析和web开发的同样占24%; 数据分析和机器学习的结合并不是什么新鲜事,但是和web开发相结合还是蛮令人惊讶的。可以肯定地说,从DevOps到机器学习和数据科学,Python无处不在。著名的编程网站Stack Overflow似乎也同意这一看法:Python是增长最快的编程语言。 13704 如果将数据分析和机器学习统称为数据科学,那么,使用Python进行web开发和数据科学的比例接近1:1。 结果:Web开发人员和数据科学家一起统治着Python世界。 Python一起使用的最流行的技术是什么? 结果显示,与Python一起使用的最流行技术是Jupyter Notebook,其次是Docker和Anaconda。 此外,接近70%的受访者使用AWS,其次是GAE,Heroku和DigitalOcean。 最后,PyCharm的两个版本是Python开发中最流行的工具,其次是Sublime,Vim,IDLE,Atom和VS Code。 本文转自:IT168网站
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签