python中接口测试垃圾数据如何清理_一个六年经验的python后端是怎么学习用java写API的(2)Extracter,微信文章抓取清洗入库...
描述
pirate 是由我的 django 脚手架 original 实现的,文件上传提供了七牛和腾讯云两个 backend,部署提供了默认的配置文件,因此只要关注具体的微信的抓取逻辑即可。
核心表讲解
pirate/original/extracter/models.py
微信文章表,正常设计,大字段拆表。
13 class WXArticle(TimeStampedModel):
14 raw_url = models.CharField(max_length=1023)
15 title = models.CharField(max_length=255)
16 cover = models.CharField(max_length=255)
17 description = models.CharField(max_length=255, default='')
18 is_active = models.BooleanField(default=False)
19 is_delete = models.BooleanField(default=False)
98 class WXArticleContent(TimeStampedModel):
99 article_id = models.IntegerField(unique=True)
100 content = models.TextField()
101 body_script = models.TextField(default='')
pirate/original/extracter/models.py
图片上传缓存表,因为有时候会重复抓取一篇文章(例如编辑后需要重新写文章),而每次抓取文章时会将里面的图片上传到我们的 cdn,添加上传文件缓存表来减少重复的图片上传操作。
188 class URLFileUploadCache(TimeStampedModel):
189 raw_url = models.CharField(blank=True, default='', max_length=512)
190 url = models.CharField(blank=True, default='', max_length=255)
191 raw_url_md5 = models.CharField(blank=True, default='', max_length=64, db_index=True)
抓取
观察微信文章发现,文章 div id=js_content 为文章正文,其中标题和 cover 图在 meta 里面,使用 requests 抓取文章原文,BeautifulSoup 过滤需要的 dom,正则找出需要替换的图片,upload_handler 选择七牛去上传图片并且替换掉原图地址。
21 @classmethod
22 def spider_url(cls, raw_url):
23 assert raw_url.startswith('https://mp.weixin.qq.com/') or raw_url.startswith('http://mp.weixin.qq.com/')
24 content = tools.spider_request(raw_url)
25 description = content_text = title = cover = ''
26 body_script = ''
27 if content:
28 b = BeautifulSoup(content, 'html.parser')
29 content_dom = b.find('div', id='js_content')
30 title_dom = b.find('meta', property="og:title")
31 cover_dome = b.find('meta', property="og:image")
32 if title_dom:
33 title = title_dom.attrs['content']
34 if cover_dome:
35 cover = cover_dome.attrs['content']
36 raw_url = cover
37 upload_cache = URLFileUploadCache.get_cached_objects(raw_url, get_last=True)
38 if upload_cache:
39 cover = upload_cache[0].url
40 else:
41 upload_data = tools.upload_file_from_url(raw_url)
42 url = upload_data['url']
43 if url:
44 URLFileUploadCache.new_cache(raw_url, url)
45 cover = url
46 if content_dom:
47 content_text = unicode(content_dom)
48 ss = b.body.find_all('script')
49 body_script = ''.join(unicode(s) for s in ss)
50 urls = []
51 for _re in constants.WEIXIN_IMAGE_RES:
52 urls.extend(_re.findall(content_text))
53 descriptions = constants.WEIXIN_DESCRIPTION_RE.findall(content)
54 if descriptions:
55 description = BeautifulSoup(descriptions[0]).meta.attrs.get('content', '')
56 mapper = {}
57 for raw_url in urls:
58 if raw_url in mapper:
59 continue
60 upload_cache = URLFileUploadCache.get_cached_objects(raw_url, get_last=True)
61 if upload_cache:
62 mapper[raw_url] = upload_cache[0].url
63 else:
64 upload_data = tools.upload_file_from_url(raw_url, )
65 url = upload_data['url']
66 if url:
67 URLFileUploadCache.new_cache(raw_url, url)
68 mapper[raw_url] = url
69 for raw_url, url in mapper.iteritems():
70 if not url:
71 continue
72 content_text = content_text.replace(raw_url, url)
73 return {
74 'raw_url': raw_url,
75 'title': title,
76 'cover': cover,
77 'content': content_text,
78 'description': description,
79 'body_script': body_script,
80 }
上传文件到七牛的 upload_handler
13 POLICY = settings.FILE_CALLBACK_POLICY or {
14 'callbackUrl': settings.FILEUPLOAD_CALLBACK_URL,
15 'callbackBody': 'bucket=$(bucket)&key=$(key)&filename=$(fname)&filesize=$(fsize)',
16 'insertOnly': 1,
17 }
18
19
20 class UploadHandler(object):
21
22 def __init__(self, key, secret, bucket):
23 self.key = key
24 self.secret = secret
25 self.bucket = bucket
26 self.backend = qiniu
27 self._backend_auth = Auth(self.key, self.secret)
28
29 def _upload_token(self, key, expires=3600, policy=None):
30 token = self._backend_auth.upload_token(self.bucket, key=key, expires=expires, policy=policy)
31 return token
32
33 def upload_file(self, key, data, policy=None, fname='file_name'):
34 if policy is None:
35 policy = POLICY
36 uptoken = self._upload_token(key, policy=policy)
37 return self.backend.put_data(uptoken, key, data, fname=fname)
38
39 def get_download_url(self, key):
40 return '{}{}'.format(settings.FILE_DOWNLOAD_PREFIX, key)
CDN 配置
创建一个公开的存储空间,名字即 FILE_UPLOAD_BUCKET
为了让域名好看一些,配置 CDN 加速域名,根据步骤操作即可(有一些 dns 的操作)。FILE_DOWNLOAD_PREFIX
个人中心秘钥管理获取 upload_handler 需要的 FILE_UPLOAD_KEY、FILE_UPLOAD_SECRET
执行部署
创建对应 mysql 数据库
创建 virtualenv,source 后 pip install 项目路径下的 requirements/base.txt
创建 config/settings/private_production.py,见下面代码段
数据库 migrate,cd 到 original 目录,执行./manage.py migrate --settings=config.settings.production
启动项目 ./manage.py runserver 0.0.0.0:8976 (端口号随意)
当然建议用 supervisor + nginx,见deploy目录下的相关例子
import os
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'dbname', # 改成你的数据库名字
'HOST': os.environ.get('ORIGINAL_MYSQL_HOST', 'localhost'), # 数据库host
'USER': os.environ.get('ORIGINAL_MYSQL_USER', 'db_username'), # 改成你的数据库user
'PASSWORD': os.environ.get('ORIGINAL_MYSQL_PASSWORD', 'db_password'), # 改成你的数据库password
'PORT': os.environ.get('ORIGINAL_MYSQL_PORT', 3306),
'OPTIONS': {'charset': 'utf8mb4'},
}
}
FILE_UPLOAD_BACKEND = 'qiniu'
FILE_UPLOAD_KEY = 'i6fdSECQjLfF' # 改成你的qiniu key,现在这里是假的
FILE_UPLOAD_SECRET = 'adfiuerqp' # 改成你的qiniu secret
FILE_UPLOAD_BUCKET = 'reworkdev' # 改成你的qiniu bucket
FILE_CALLBACK_POLICY = {}
FILE_DOWNLOAD_PREFIX = '' # 改成你的host, 例如 http://cdn.myhost.com/
FILEUPLOAD_CALLBACK_URL = # 改成你自己host的对应地址, 例如 https://www.myhost.com/api/v1/file/upload/callback/
postman 测试接口
查看数据库
接下来
基本物料接口准备就绪,下面就可以正式开始 Java 框架的学习。
python中接口测试垃圾数据如何清理_一个六年经验的python后端是怎么学习用java写API的(2)Extracter,微信文章抓取清洗入库...相关推荐
- python中接口测试垃圾数据如何清理_巧用PyUnit中unittest特性解决接口测试产生脏数据问题...
巧用PyUnit中unittest特性解决接口测试产生脏数据问题 一.背景 测试数据创建后需要对其删除,不然可能产生脏数据,对开发和测试.生产环境造成一定影响.其接口框架是基于Python,API规范 ...
- python中接口测试垃圾数据如何清理_接口测试---Python数据处理需要注意的细节
一.json模块中的dumps方法 请求接口时params肯定是dict类型的,就是这种{"A":"B"},因为需要传json格式的参数到服务端,但是为了降低c ...
- python中接口测试垃圾数据如何清理_Python接口测试题(持续更新中)
1.json和字典的区别? Json是轻量级的数据交互格式,以key-value的键值对形式来保存数据,结构清晰,可以说是目前互联网项目开发中最常用的一种数据交互格式. 字典,同样是以key-valu ...
- python后端需要什么基础_一个六年经验的python后端是怎么学习用java写API的(6) 基本的Auth...
描述 实现了依赖注入之后就可以方便的实现各种API的业务逻辑了,下一部的问题就在于权限,我们知道大部分的系统API并不是开放的,需要基本的用户体系(注册.登录.购买.会员.不同的role等等),例如管 ...
- python两个字符串数据可以复制吗_无论如何,是否要将Python pandas数据框中的单个数据中的数据复制到字符串或列表中以进行进一步处理?...
使用示例数据.请注意,由于复制和粘贴选项卡占用空格(因此使用sep ='\ s +',iso'\ t')并且我已将数据的第一行设置为列名(不使用header = None).可以使用join将一列连接 ...
- python中的库有哪些餐厅_推荐一些实用的的 Python 库
Python Python开发 Python语言 推荐一些实用的的 Python 库 一门语言好用.方便的程度在很多时候会取决于这门语言相关的库够不够丰富,Python 之所以火爆除了其本身的语法和特 ...
- python中使用什么命令安装组件_在离线环境下安装python组件
在一些项目中,我们会不可避免地使用到python组件,而生产环境大多数服务器是没有办法直接联网下载python的包的.当然,有的小伙伴会很聪明地把这个包的whl下载下来到服务器上去执行,但是会得到这样 ...
- python中csv库的writer函数_指定格式csv.writer在Python中
我正在使用csv.DictWriter从一组词典输出csv文件.我使用以下函数:def dictlist2file(dictrows, filename, fieldnames, delimiter= ...
- python类型转换-Python中如何进行数据类型转换?
原标题:Python中如何进行数据类型转换? 这一次要讲的是Python中的数据类型转换,Python中的数据类型转换是什么?就是将数据由当前类型变化为其他类型的操作就是数据类型转换.数据类型转换分为 ...
最新文章
- zookeeper java.env_zookeeper在生产环境中的配置(zookeeper3.6)
- .NET中,字符串首字母大写的方法
- Ubuntu 12.04 Server 搭建DNS服务器
- git 本地仓库同时推送到多个远程仓库
- 现代软件工程系列 学生和老师都不容易
- Oracle数据库中的dual表
- php如何安装mysql模块,linux安装php 模块--with-mysql --with-mysqli非得需要安装mysql吗汗血宝马...
- android input 点击事件失效,React Native:TextInput元素上的onContentSizeChange事件在Android上不起作用...
- Java的值类型(基本类型)和引用类型
- 权力的游戏登录显示服务器上限,权力与纷争登录不上怎么办 登录不上解决方案...
- linux抓包-tcpdump
- 技嘉主板bios设置方法
- Python实现BT种子转化为磁力链接
- 百度地图API基本使用(二)
- Android动态获取权限(读写、获取手机状态、定位)
- excel文档文件加密的方法步骤
- 一个控制键盘远程控制多台视频会议摄像机(转自搜狐)
- 常见外包公司(非全部)
- vue使用d3数据可视化(柱状图、饼图、折线图 带坐标轴)
- position定位的属性