From 94c11218edb9e55b2ba0734abd1d04e7ae6a96b7 Mon Sep 17 00:00:00 2001 From: MengXiang Date: Mon, 9 Apr 2018 10:03:28 +0800 Subject: [PATCH] add get article_detail and test(#190) * add get article_detail and test --- requirements.txt | 1 + test/file/article_detail_backgroud-image.html | 2739 +++++++++++++++ test/file/article_detail_expired.html | 146 + test/file/article_detail_iframe.html | 2376 +++++++++++++ test/file/article_detail_mpvoice.html | 2957 +++++++++++++++++ test/file/article_detail_qqmusic.html | 1372 ++++++++ test/test_api.py | 19 + test/test_structuring.py | 64 +- wechatsogou/api.py | 95 +- wechatsogou/identify_image.py | 1 - wechatsogou/structuring.py | 99 +- 11 files changed, 9848 insertions(+), 21 deletions(-) create mode 100644 test/file/article_detail_backgroud-image.html create mode 100644 test/file/article_detail_expired.html create mode 100644 test/file/article_detail_iframe.html create mode 100644 test/file/article_detail_mpvoice.html create mode 100644 test/file/article_detail_qqmusic.html diff --git a/requirements.txt b/requirements.txt index 3441a5a..e71f69f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ requests==2.18.2 six==1.10.0 Werkzeug==0.12.2 xlrd==1.0.0 +bs4==0.0.1 \ No newline at end of file diff --git a/test/file/article_detail_backgroud-image.html b/test/file/article_detail_backgroud-image.html new file mode 100644 index 0000000..9584c40 --- /dev/null +++ b/test/file/article_detail_backgroud-image.html @@ -0,0 +1,2739 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 4月6日周五【新闻速览一分钟】 + + + + + + + + + + +
+
+ + +
+ +
+ +

+ 4月6日周五【新闻速览一分钟】

+
+ 2018-04-06 + + 🌏华商君 + 华商报 + 华商报 + + + +
+ + +
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+

+  早上好~

+
+

不要总呆在自己的舒适圈里, +

+

+ 不走出去,

+

你很难发现自己的潜力 +

+
+
+
+
+
+

+ +

+
+
+
+
+
+
+
+
+
+
+


+
+
+
+
+
+
+
+ 华商新闻
+
+
+
+
+

●4月5日上午9时50分许,戊戌(2018)年清明公祭轩辕黄帝典礼在黄陵举行。万余名海内外中华儿女齐聚黄帝陵轩辕殿祭祀广场,共同祭奠人文始祖轩辕黄帝,一带一路、精准脱贫、翱空潜海、扩绿治污等被写入祭文。 +

+

+


+
+
+
+

+

向上滑动阅览

+
+
+
+

戊戌年清明公祭轩辕黄帝文

+


+

   岁在戊戌,节届清明,桥山之阳,春和景明。华夏儿女以笃恭笃敬之心、八佾(yì)雅乐之仪,祭告轩辕黄帝曰: +

+

   + 吾祖赫赫,伟业煌煌,肇始文明,光被遐荒。制礼作乐,教民德尚,行造舟车,医重岐黄。青史源悠悠兮瓜瓞(dié)芃芃,斯民亿万万兮社稷泱泱。世代传薪,余烈久长,俎豆千秋,礼乐馨香。 +

+

   + 壮哉中华,乾坤朗朗;自信在胸,正道康庄。国力宏勃兮光灿寰宇,民心齐荟兮奋发图强。盛会十九大,砥砺前行初心不忘;开启新时代,思想引领伟业恒昌。宪法修立兮万众尊崇,纲纪整饬兮政风和畅。一带一路连五洲命运,精准脱贫惠华夏山乡。翱空潜海创新加速,扩绿治污沃野新妆。一国两制,紫荆白莲繁花并蒂;两岸一家,四海宇内祈合共襄。万山磅礴,主峰雄踞;千帆竞发,舵手领航。励精图治,奋楫劈波斩浪;伟大复兴,圆梦百年沧桑。 +

+

   + 三秦故地,再谱华章。追赶超越,其时正当。五个扎实并举,一幅蓝图宏昶(chǎng)。百姓广增福祉,经济新阶再上。高质量发展聚能增效;自贸区运转达海通江。牢记嘱托,埋头苦干开来继往;情系人民,上下同心共筑辉煌。 +

+

   + 桥山巍巍,古柏苍苍,人文初祖,勋耀洪荒。冀佑中华祥瑞,福泽天下安康。大礼告成,伏惟尚飨!

+
+
+
+


+

● 清明小长假首日出行,大半天堵在路上。昨日西安绕城高速、西禹高速、西柞高速、西汉高速均严重堵车,直到下午2时许,逐渐恢复正常。明日(4月7日)下午3时至晚9时为返程高峰,拥堵程度将明显大于首日出行时段,大家提前做好规划。

+

+


+

15岁智障男孩任某被人殴打后吊绑在铁柱上身亡,犯罪嫌疑人为曾有精神病史的男子王某。昨日,周至警方已将王某刑事拘留。任某的奶奶表示家人并不认识王某。对于王某作案意图和作案时是否发病等情况,警方仍在进一步调查。   +

+

+

+


+

● + 受强冷空气影响,预计6日陕北有7级左右偏北风、关中、商洛有4-6级偏北风,伴有扬沙或浮尘,气温下降6℃左右,陕北、关中北部有霜冻。  +

+


+

● + 截至4月5日18时,西安车站单站日发送旅客15.28万人,全站发送旅客21.21万人,突破今年春运的最高记录。今明两天,高铁方面,西安北去往北京、上海、成都等方向的列车车票基本售罄

+

+


+

● + 西安实施“烟头革命”以来,不少单位都积极响应,还采取上街捡烟头、发放灭烟盒等措施,如今一年多过去了,街上烟头为啥还这么多?记者回访发现,一些人习惯性地乱扔烟头,一些灭烟器被共享单车包围使用不便。

+

+


+

+ ● 抢购前,网络宣称套餐可在三个月内使用,抢购后突然变3天,西安浐灞艾美酒店268元自助套餐“说变就变”。律师:消费者有权3倍索赔,建议向工商部门投诉。

+

+


+

● 长安区杜东村村民赵先生买到豆腐砖,一捏就碎,砖上没有任何可显示厂家或批号的标识。华商报记者联系砖厂,工作人员称老板回老家了,收假后将立即回复。昨日下午5时许,记者再次拨打该电话时,已无人接听。至于同批砖块到底卖出了多少块?都流向了哪里?华商报将继续关注。 +

+

+


+

● 清明小长假期间,执法人员对城西客运站周边的黑车进行查处,执法过程中,有些坐着黑车的乘客认为黑车方便,忽视出行安全,不愿下车。

+

+


+

● 4月4日,咸阳永寿县甘井镇北甘井村在流转土地过程中发生冲突,致一村民受伤死亡。目前警方已将一名涉案人员刑事拘留。县政府5日通报称,镇党委书记、镇长被就地免职。

+

+

+


+

● 渭南蒲城县两小学给学生定制礼服,价格根据不同尺码从280元到360元不等。有家长认为,衣服价格太高但质量不高,孩子已有多套校服,这次购买也未提前通知家长,是变相强制购买。县教育局:开过家长代表会,未强制购买,定制相比普通校服价格高一些。

+

+

+


+

● 陕西靖边庙梁遗址考古取得重要收获:庙梁遗址与石峁遗址应该有一定联系。距今已有4000年的神木县石峁遗址被称为“中国文明的前夜”,而庙梁遗址呈现的则是“石峁文化”前的文化遗存。“石峁文化”用年轻人做祭祀,庙梁遗址灰坑中发现的少年,很有可能也是用来祭祀的。

+

+

+


+

● 商洛市江南小区东片区有1160户住户,近日,业主买电时被物业限电,一次只让买20元电。部分住户为了省电,晚上打手电筒。物业称,2011年至今近900户住户未交物业费,限电属无奈之举。 +

+


+

● 近日,汉中市民反映火车站南广场部分地砖高低不平,未采取固定措施,行人通行容易磕绊,存在安全隐患。对此,项目部称因工期紧,材料不全,“干铺”为临时措施,将立即处理。

+

+

+

+


+

+

+


+
+
+
+
+
+
+ 热点资讯
+
+
+
+
+


+

+

● + 5日,中国就美国进口钢铁和铝产品232措施,正式在世贸组织起诉美国。商务部表示,鉴于美方拒绝根据世贸规则与中方进行补偿谈判,中方不得不启动争端解决程序,捍卫合法权益。 +

+


+

+

● 4日公安部通报,2017年共361名公安民警(含公安现役官兵)因公牺牲,有6234人因公负伤或致残。其中,因劳累过度猝死在工作岗位上的公安民警有246人。此外,过去的一年有126名辅警因公牺牲。 +

+

+

+


+

+

● 广西34岁的严锋去年确诊患上白血病,全家只有8岁的儿子配型成功且适合捐赠。由于儿子年纪小且体重轻,需要全身麻醉连续采集两天。儿子说:“只要能救爸爸,再痛也不怕。

+

+


+

● + 近日有媒体发布的一则“港珠澳大桥主体工程人工岛岛头的防波堤被海浪冲散?”的报道引起社会关注。对此,港珠澳大桥管理局回应称“相关报道涉及的港珠澳大桥人工岛岛头位置防波堤为特殊设计,报道为不实报道。” +

+

+


+
+

● 3月30日早上7点,苏州一名50多岁的男子上公交时表示自己在赶火车很着急,指责驾驶员张师傅开车慢。张师傅赶紧解释,可男子并不理会,反而伸手抢夺方向盘,表示让他来开,张师傅见状立即报警。

+

+


+

● 63岁的张振林是南京的一名守墓人,8年前爱人去世,他辞掉原来的工作,到安葬妻子的墓园做守墓人。他用积蓄买了个双人墓,每天都到妻子的墓前看看。"我想你了,看不到你了,就看看相片了…"

+

+


+

● 4月3日,江西福银高速,一辆载有9吨苹果的货车侧翻,苹果散落一地,当地村民拿着蛇皮袋、水桶等工具到现场哄抢,场面混乱。现场交警极力阻拦无效,喊来民警后,局面虽被控制,但苹果已所剩无几

+

+


+
+
+
+


+
+
+
+
+
+
+
+ 天下博览
+
+
+
+
+

● 美欧多国联手驱逐俄罗斯外交官后,禁止化学武器组织4日就俄前特工中毒案召开特别会议。这是3月初中毒案爆发后英俄双方首度“对簿公堂”

+


+

● 日前,一名女枪手闯入视频网站YouTube美国加州总部的大楼,开枪伤3人后自杀。经初步调查发现,枪手疑因不满多次被YouTube删除视频片段,导致其失去收入,因此怀恨在心到总部开枪报复。 +

+

+


+

● 沙特阿拉伯文化新闻部宣布,沙特第一家电影院将在首都利雅得开张。这是沙特电影院禁令实施35年来,沙特民众将首次在本国电影院观看电影。 +

+


+

● 昨天下午,一架从韩国大邱基地起飞的疑似F-15k战斗机在韩国庆北漆谷郡坠落,目前已经找到了飞机残骸,机上共有二名飞行员,一人死亡一人重伤。 +

+


+

塞拉利昂最大反对党塞拉利昂人民党总统候选人朱利叶斯·马达·比奥在大选宣布获胜后不久,在首都弗里敦宣誓就任总统。

+

+
+


+
+
+
+
+
+

+ 欢迎分享到朋友圈~ +

+

+

+
+
+
+
+

+

+

+

+
+

+

+
+ + + + + + + + +
+ +
+ + + + + + + + +
+ + +
+ + +
+
+ + + + +
+ + +
+ + + + + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/file/article_detail_expired.html b/test/file/article_detail_expired.html new file mode 100644 index 0000000..2ba338f --- /dev/null +++ b/test/file/article_detail_expired.html @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+

+ 链接已过期 +

+
+
+ + + + + + + + + + + + + + diff --git a/test/file/article_detail_iframe.html b/test/file/article_detail_iframe.html new file mode 100644 index 0000000..76fa3d8 --- /dev/null +++ b/test/file/article_detail_iframe.html @@ -0,0 +1,2376 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 【视频】石榴花开 + + + + + + + + + + +
+
+ + +
+ +
+ +

+ 【视频】石榴花开

+
+ 2018-03-20 + + 共产党员 + 共产党员 + + + +
+ + +
+ + +

+

+

+ +
+

+

+

+

“各民族要相互了解、相互尊重、

+

相互包容、相互欣赏、 +

+

相互学习、相互帮助, +

+

像石榴籽那样紧紧抱在一起。”

+

 

+

+

 

+

两会

+

春天的盛会

+

 

+

56个民族的代表齐聚北京

+

共商国是

+

共谋发展

+

 

+

+

 

+

新时代

+

新气象

+

新作为

+

 

+

(来源:新华社)

+

+

+
+ + + + + + + + +
+ +
+ + + + + + + + +
+ + +
+ + +
+
+ + + + +
+ + +
+ + + + + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + diff --git a/test/file/article_detail_mpvoice.html b/test/file/article_detail_mpvoice.html new file mode 100644 index 0000000..cb11149 --- /dev/null +++ b/test/file/article_detail_mpvoice.html @@ -0,0 +1,2957 @@ + + + + + + + + + + + + + + + + + + + + + + + + + 语音 | 早安武汉〔2018.3.19 周一〕 + + + + + + + + + + +
+
+ + +
+ +
+ +

+ 语音 | 早安武汉〔2018.3.19 周一〕

+
+ 2018-03-19 + + 读武汉关注☞ + 长江日报 + 长江日报 + + + +
+ + +
+ + +

+ +

+
+
+
+
+

【全国两会】

+
+
+
+
+

+

十三届全国人大一次会议昨日上午在人民大会堂举行第六次全体会议,根据国家主席习近平的提名,经过投票表决,决定李克强为中华人民共和国国务院总理。国家主席习近平签署第一号主席令,根据大会决定,任命李克强为国务院总理。 +

+

经投票表决,十三届全国人大一次会议决定许其亮、张又侠为中华人民共和国中央军事委员会副主席;决定魏凤和、李作成、苗华、张升民为中华人民共和国中央军事委员会委员。 +

+

杨晓渡当选为中华人民共和国国家监察委员会主任。

+

周强当选为中华人民共和国最高人民法院院长。 +

+

张军当选为最高人民检察院检察长。 +

+
+
+
+
+
+
+
+
+
+

今日议程 +

+


+

+

十三届全国人大一次会议举行第七次全体会议,决定国务院副总理、国务委员、各部部长、各委员会主任、中国人民银行行长、审计长、秘书长的人选,表决十三届全国人大民族委员会、监察和司法委员会、教育科学文化卫生委员会、外事委员会、华侨委员会、环境与资源保护委员会、农业与农村委员会、社会建设委员会主任委员、副主任委员、委员名单草案。 +

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

【武  汉】

+
+
+
+
+
+
+
+
+
+
+
+
+
+

+

◇ 周四,2018年第二批武汉百万校友资智回汉•湖北大学专场将举行。湖大将与武汉市在新材料、新能源、信息技术等方面开展合作。

+

+

记者从武汉市纪委获悉,因用公款旅游、违规公务接待、违规发放津补贴,且履职尽责不力,蔡甸区芦苇总站负责人受到党内严重警告处分。

+


+

记者从武汉市纪委获悉,单位违规发放津补贴、用公款报销,武湖农业发展公司负责人因履责不力受到党内警告处分。 +

+

+

周末两天近5万游客涌入东湖樱园,其中包括200多组外地旅游团队

+

+

+

+

+

◇ 17日、18日,2018年武汉市艺术小人才比赛全面拉开,来自全市各个中小学的3700余名小选手纷纷亮出自己的才艺绝活。

+

17日,湖北省内外132家医院齐聚武汉,成立“湖北省结核病专科联盟”。

+

全国首个儿童移动监护病房近日在汉启用,这也是目前国内最先进的儿童(新生儿)急救转运车,更多周边地区的危重患儿将通过它安全地转到武汉救治。

+

晚进行的中甲次轮赛事中,卓尔客场一波三折,最终3:2击败浙江毅腾队,取得新赛季开局两连胜。 +

+

昨日,356名跑友成功挑战武汉世纪中心垂直马拉松。其中,速度最快的选手仅用6分13秒就爬上42层高楼。

+

+

+

+

电影《遇见你真好》观众见面会上的范明 记者刘洪洋 摄

+

顾长卫导演的电影《遇见你真好》将于近日上映,昨日,演员范明、曹骏及武汉姑娘王玉雯与武汉观众见面,60后范明直说缅怀青春让他饱含热泪。

+
+
+
+

【天  气】

+
+
+
+

+

+

+

昨日二月二,孩子们舞龙欢庆“龙抬头”   记者李子云 摄 +

+


+

气象台预计,今明依旧是阴雨绵绵、北风劲吹,周三开始转为多云天气,气温缓慢回升。

+

+

具体预报:今天白天,阴天转小雨,6℃~10℃,偏北风3到4级,阵风5到6级;今晚到明天白天,小雨转阴天,6℃~10℃,偏北风3到4级,阵风5到6级。 +

+
+
+
+
+

【提  醒】

+
+
+
+
+

+

+

3月21日起至9月30日,汉阳区夹河路(马鹦路至鹦鹉大道)将进行排水工程施工。施工期间,夹河路(马鹦路至鹦鹉大道)禁止机动车通行。需通行施工路段的机动车,可绕行国博大道、鹦鹉大道、马鹦路等周边道路。 +

+

为保障2018年樱花节及春游期间交通安全畅通,交管部门对部分道路实行临时交通管制措施。 +

+

武大周边:24日、25日、31日、4月1日、5日、6日、7日每日9:00至18:00,以下道路实行临时交通管制措施:行经珞狮路(八一路至洪山侧路)、珞狮北路(珞喻路至八一路)、洪山侧路(珞狮路至东三路)实行机动车按车牌尾号分单双号通行(公交车、出租车除外);珞珈山路(珞狮路至武大牌坊)、八一路地下通道辅道禁止机动车通行(公交车除外);珞狮路(珞喻路至洪山侧路)两侧禁止机动车停放。 +

+

东湖周边:24日、25日、31日、4月1日、5日、6日、7日、14日、15日、21日、22日、28日、29日、30日、5月1日,每日9:00-18:00,东湖沿湖大道(梨园大门至东湖大门)、梨园广场北通道、鲁磨路(团山路路口至樱花园大门)、植物园路(团山路至鲁磨路)、东湖南路(东湖东路至天鹅路)、卓刀泉北路(东湖南路至八一路路口)实行机动车按车牌尾数分单双号通行(出租车、公交车、9座以上大中型客车、外埠车辆、新能源车除外)。 +

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

【城市留言板】

+
+
+
+
+
+
+
+
+
+

+

+

+

本周,武汉市网上群众工作部武汉城市留言板10家入驻单位将“在线轮值”,上线长江网回答网民提问。其中,武汉市科协、武汉市社科院今天在线。 +

+


+

“在线值班”表 +

+


+

+

3月19日 市科协、市社科院 +

+

3月20日 武汉供电公司、市天然气公司 +

+

3月21日 市水务集团、中石化武汉分公司 +

+

3月22日 市文联、市残联 +

+

3月23日 贸促会武汉分会、市供销合作总社 +

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


【天  下】

+
+
+
+
+
+
+
+
+
+

+

当地时间3月16日,美方签署“与台湾交往法案”。中国外交部、国防部、国台办、驻美使馆分别对此进行回应:我们坚决反对!

+

+

《关于对失信被执行人实施限制不动产交易惩戒措施的通知》近日下发, 共同对失信被执行人及失信被执行人的法定代表人、主要负责人、实际控制人、影响债务履行的直接责任人员,采取限制不动产交易的惩戒措施。

+


+

经过20年不懈努力,我国主要天然气消费区已建成储气库25座,为2亿居民生活提供了保障。

+

+

+

+

李敖 资料图

+

罹患脑干肿瘤的作家李敖,昨日上午离世,享年83岁。详情>>>

+

近日,中国睡眠研究会发布《中国睡眠诊疗现状调查报告》及《2018中国互联网网民睡眠白皮书》。数据显示,失眠重度患者超六成为90后,集中在北上广等城市。 +

+

国际足联主席因凡蒂诺近日宣布,国际足联已经决定在6月举行的俄罗斯世界杯上,首次采用“录像裁判”技术。

+
+
+
+
+
+
+
+
+
+
+
+
+

【历史印记】

+
+
+
+
+

+

+

2004年3月19日,中国第一个下一代互联网主干网在北京正式开通并提供服务,连通上海、广州和北京。 +

+
+
+
+
+
+
+
+

+
+
+
+
+

【福  利】

+
+
+
+
+

+

+

+

+

+

扫描上方图片二维码领取ofo小黄车骑行礼包! +

+
+
+
+
+
+
+
+
+
+

【生  活

+
+
+
+
+
+
+
+
+
+

+

【10种会折寿的生活习惯】1.长时间对着电脑。2.晚上十一点以后睡觉。3.不能保证睡眠时间。4.极度缺乏体育锻炼。5.有病不求医。6.吃饭口味偏重特别喜食咸的和辣的。7.不饿不吃、不困不睡、不累不息。8.与家人缺少交流。9.长时间用手机打电话。10.三餐饮食无规律。 +

+

+
+
+
+
+

【话  题】

+
+
+
+
+

+

+

+

+


+

又到一年三四月,正是春招火热时。调查显示,不少白领不满3年就频繁跳槽,你怎么看? +

+

+

+

+

+
+
+
+
+
+
+
+
+
+
+

【最佳留言】

+
+
+
+
+
+
+
+
+
+

+

+

+

+

+

昨天最早留言的前十位网友是:@北街末雨、@*我就是我*、@李平、@桂加国、@黄文毅、@zg(wh)龚永前、@老五、@遠方、@音乐虫子、冯贤桥 +

+

+

+
+
+
+
+
+
+
+
+
+

【早安心语】

+
+
+
+
+
+
+
+
+
+

+

人对他人的需求越少,就会活得越自如越安详。没有人,哪怕他愿意,也不可能完全满足另一个人的需要,唯一的办法就是令自己的需要适可而止。 ——廖一梅 +

+

+

+
+

来源|长江日报及新华社、人民日报、央视新闻等 +

+

编辑|张维纳 语音|徐佳 剪辑|李春 制图|张莉 校读|刘永杰 +

+

投稿|cjrb027@qq.com  合作|whcjrb027(微信) +

+
+ + + + + + + + +
+ +
+ + + + + + + + +
+ + +
+ + +
+
+ + + + +
+ + +
+ + + + + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + diff --git a/test/file/article_detail_qqmusic.html b/test/file/article_detail_qqmusic.html new file mode 100644 index 0000000..f8f118c --- /dev/null +++ b/test/file/article_detail_qqmusic.html @@ -0,0 +1,1372 @@ + + + + + + + + + + + + + + + + + + + + + + + + 关于音乐 + + + + + + + + + + +
+
+ + +
+ +
+ +

+ 关于音乐

+
+ + 2018-04-07 + + 闲云野鹤 + 闲云野鹤古刹 + 闲云野鹤古刹 + + + +
+ + + + + + + +
+ + + + + + +

文艺青年消遣有四大法宝:读书、旅行、运动与音乐。读书是最奢侈的享受,读书不是看书,而有选择的汲取。旅行不是旅游,是去自己想去的地方,过程远比目的地重要。运动不是体育,只看不做是没有任何意义的。音乐不仅仅是歌曲,任何能打动人的声音都可以称为音乐。

很小的时候,没有收音机、没有电视,大自然的音乐伴随着我的成长。我家住在半上腰上,三面环山,一面朝向山谷。破晓时分,就能听到公鸡打鸣的声音。黎明时分,山上的布谷鸟等鸟类就会陆续发出清脆的啼声。清晨时分,奶奶做早餐声音,听着就让人觉得很美味。上午时分,劳作的声音,有挖土的,有耕田的,有施农药的,有打化肥的。午睡时分,爷爷的鼾声,小猫的呼噜声,蝉的鸣叫声。傍晚时分,劳作回家的脚步声,放学的尖叫声,蛐蛐的合奏声,猫头鹰的恐吓声。晚上,蛙声,山风呼啸的声音,犬吠声。

第一次真正的接触音乐是小学的语文老师。她会弹钢琴,兼职我们的音乐老师,每节音乐课都会教我们唱一首歌。

村里的红白喜事,一般流行“打渔鼓”,这是我们家乡特色的戏曲,一个蒙上猪皮膜的“渔鼓筒”就是演奏乐器。

有了电视之后,央视的大风车,热播电视的主题曲,新闻联播之后点歌时间,都是儿时汲取音乐的时间。

买了VCD、DVD之后,家里播放的是什么十三大美女之类的歌曲,院子里的男女老少都会过来凑凑热闹。

初中的时候,晚自习前的半个小时便是音乐时间。可以集体唱歌、学歌,或者个人表演。记得有一年,刚好停电了,大家都自告奋勇的上台表演。我也鼓起勇气趁着漆黑上去唱了一首任贤齐的《任逍遥》,结果唱到一半的时候来电了,大家齐刷刷的盯着我,只能在煎熬与害羞中唱完此歌。

初中前期流行F4、黄家驹、林志炫的歌曲,后期流行任贤齐、周杰伦的歌曲。尤其《单身情歌》当时特别的火爆,几乎人人会唱。大家都有一本专门的本子,用来抄写歌词。记得一次上生物课,有人在课上抄写歌词,被老师逮住了,让他当着大家的面把歌词读了一遍。那时,因为没有零花钱,买有过任何的磁带,只能借大家的听。

高中的时候流行周杰伦、王力宏、蔡依林、SHE的歌曲。当然还有林俊杰、阿杜、潘玮柏、张韶涵、梁静茹等,只是相对前四位人气稍逊。尤其是刀郎的横空出世,带给大家很多的惊喜。

高中的每个教室有一个很大的电视用来播放视频。同样晚自习前的半个小时也是娱乐时间。很巧的是,又一次停电,这一次,我没有参加。我记得我的同桌上去唱了一首《发如雪》,他蹩脚的普通话,不在调上的歌声让大家印象深刻。最出彩的还不是他,另一个同学硬是在没有伴奏的情况下,唱完了《心中的日月》,同样是唱到一半的时候来电了,让拿着试卷准备晚上考试的数学老师皱着眉头听完了。

那时我对流行音乐是抗拒的,大家都听的,我越不想随波逐流。我买的专辑是苏有朋、林志颖、潘玮柏的。记得当时我在听苏有朋的歌曲,我的另一个同桌很好奇我在听什么,于是就让我分享一个耳机给他,他听了不到几秒钟,然后马上把耳机甩给我,配上一脸皱眉和嫌弃的表情,让我很生气。音乐没有高低,你可以不喜欢,但你所作所为,让人觉得非常没有教养。

大学的时候,开始接触到了网络,也可以听到更多类型的歌曲。这个时期最喜欢的还是周杰伦,他开创的中国风歌曲是我的最爱。

因为中国风,我还喜欢上了许嵩的音乐。许嵩是一个独立音乐人,从作词作曲配乐到后期制作都是自己一手完成的。他的歌词是我认为唯一可以媲美方文山的,作曲是唯一可以媲美周杰伦的。

光良纯纯的情歌俘获了无数的人心声。对于情窦初开的少男少女,光良和无印良品的歌曲绝对能打动你们。

李圣杰绵绵情歌是疗伤的绝佳圣药。他独特的嗓音,熟悉的旋律让你难以抗拒。

张杰在沉寂之后的一炮而红,清新的歌曲风格,也是深受大家的喜爱。

女歌手中最喜欢的是张惠妹,她能驾驭各种曲风。无论是快歌中狂野、洒脱、不屑、报复,抑或慢歌中乞求、深情、豁达、撕心裂肺,都能让你获得满满的力量。无论你的感情状况如何,总有一首适合你。

第一次接触KTV是去农家乐的时候。破旧的音响设备不是重点,重要的是第一次可以跟着伴奏唱歌,第一次听到自己通过话筒的声音。后来一发不可收拾,经常与一群好友通宵去唱歌,哪怕第二天没钱吃饭。

大学时候歌唱比赛,唱了一首周杰伦的《菊花台》,自己觉得还行,没有获奖。大学毕业晚会,与同学合唱了一首李圣杰的《你那么爱她》,不知道效果效果如何,唱完就溜了。

毕业之后,没有一个值得关注的歌手。很多歌手都是在拼高音,拼节奏,把人推向一个永不满足的深渊,而忘了安静唱歌、好好唱歌的初衷。如果非要说一个,只能推荐让人耳目一新的李荣浩。民谣也是最近比较喜欢的风格,比如赵雷等一些小众的歌手。

在西藏和云南旅行期间,对少数民族的原生态大碟比较感兴趣,无奈囊肿羞涩,没有购买。有一段时间比较迷恋齐豫唱的佛教歌曲,能让人浮躁的心情立即安静放松。最佳嗓音当然非周深莫属,听他的歌就是一种享受。

毕业后在新生的茶话会上,演唱了一首张杰的《明天过后》,貌似受到了大家的喜欢。后来参加公司组织的歌唱比赛,演唱庾澄庆的《春泥》,结果一上台舌头打结,在评委给了一次重新演唱的机会后,还是没能摆脱第一轮被刷的悲惨命运。再后来玩起了唱吧,就再也没有去过KTV了。

经历岁月的变迁,最喜欢的还是李圣杰,一直觉得他是实力与完美嗓音结合体。尽管今年参加歌手时的名次不佳,名气也大不如从前,但你的歌声和旋律,在我的心中谁也替代不了。


如你觉得文章不错,请识别图中二维码关注,并推荐给你的朋友,感谢你的分享,2018年请给自己一份惊喜。

+
+ + + + + + + + + +
+ +
+ + + + + + + + +
+ + +
+ + + +
+
+ + + + +
+ + +
+ + + + + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + diff --git a/test/test_api.py b/test/test_api.py index 724c872..bb40cdf 100644 --- a/test/test_api.py +++ b/test/test_api.py @@ -3,6 +3,7 @@ from __future__ import absolute_import, unicode_literals, print_function import os +import time import unittest from nose.tools import assert_equal, assert_true, assert_in, assert_greater_equal @@ -52,6 +53,24 @@ def test_get_sugg(self): sugg_gaokao = ws_api.get_sugg(gaokao_keyword) assert_equal(10, len(sugg_gaokao)) + def test_get_article_content(self): + gzh_article = ws_api.get_gzh_article_by_history(gaokao_keyword, + identify_image_callback_sogou=self.identify_image_callback_sogou, + identify_image_callback_weixin=self.identify_image_callback_ruokuai_weixin) + assert_in('gzh', gzh_article) + assert_in('article', gzh_article) + assert_in('wx.qlogo.cn', gzh_article['gzh']['headimage']) + assert_greater_equal(len(gzh_article['article']), 1) + # 防止测试时被封IP + time.sleep(11) + article_url = gzh_article['article'][0]['content_url'] + + article_info = ws_api.get_article_content(article_url, + identify_image_callback=self.identify_image_callback_sogou) + + assert_in('content_html', article_info) + assert_in('content_img_list', article_info) + if __name__ == '__main__': unittest.main() diff --git a/test/test_structuring.py b/test/test_structuring.py index 6b9e320..1e53068 100644 --- a/test/test_structuring.py +++ b/test/test_structuring.py @@ -2,16 +2,17 @@ from __future__ import absolute_import, unicode_literals, print_function +import datetime import io -import os import json +import re +import os import unittest -import datetime +from bs4 import BeautifulSoup +from nose.tools import assert_equal, assert_in, assert_true, assert_greater_equal, assert_is_none, assert_not_in -from nose.tools import assert_equal, assert_in, assert_true, assert_greater_equal - -from wechatsogou.structuring import WechatSogouStructuring from test import fake_data_path, gaokao_keyword +from wechatsogou.structuring import WechatSogouStructuring assert_equal.__self__.maxDiff = None @@ -372,6 +373,59 @@ def test_get_article_by_search_wap(self): 'oIWsFt3nYBUhqb4beN3rTBxdUHD8'], open_ids) + def test_get_article_detail(self): + file_name = os.path.join(fake_data_path, 'article_detail_backgroud-image.html') + with io.open(file_name, encoding='utf-8') as f: + text = f.read() + + article_detail = WechatSogouStructuring.get_article_detail(text) + assert_equal(len(article_detail['content_img_list']), 29, article_detail) + assert_true('data-wxurl' not in article_detail['content_html'], article_detail['content_html']) + assert_true('qqmusic' not in article_detail['content_html'], article_detail['content_html']) + # 图片有src属性,无data-src属性 + content_html = BeautifulSoup(article_detail['content_html'], 'lxml') + imgs = content_html.find_all("img", src=re.compile(r'http')) + assert_equal(len(imgs), 29, imgs) + for img in imgs: + assert_is_none(img.attrs.get('data-src')) + + file_name = os.path.join(fake_data_path, 'article_detail_mpvoice.html') + with io.open(file_name, encoding='utf-8') as f: + text = f.read() + + article_detail = WechatSogouStructuring.get_article_detail(text) + assert_equal(len(article_detail['content_img_list']), 9, article_detail) + assert_true('data-wxurl' not in article_detail['content_html'], article_detail['content_html']) + assert_true('qqmusic' not in article_detail['content_html'], article_detail['content_html']) + assert_true('mpvoice' not in article_detail['content_html'], article_detail['content_html']) + + file_name = os.path.join(fake_data_path, 'article_detail_qqmusic.html') + with io.open(file_name, encoding='utf-8') as f: + text = f.read() + + article_detail = WechatSogouStructuring.get_article_detail(text) + assert_equal(len(article_detail['content_img_list']), 2, article_detail) + assert_true('data-wxurl' not in article_detail['content_html'], article_detail['content_html']) + assert_true('qqmusic' not in article_detail['content_html'], article_detail['content_html']) + assert_true('mpvoice' not in article_detail['content_html'], article_detail['content_html']) + + file_name = os.path.join(fake_data_path, 'article_detail_iframe.html') + with io.open(file_name, encoding='utf-8') as f: + text = f.read() + + article_detail = WechatSogouStructuring.get_article_detail(text) + assert_equal(len(article_detail['content_img_list']), 6, article_detail) + assert_not_in('data-wxurl', article_detail['content_html'], article_detail['content_html']) + assert_not_in('qqmusic', article_detail['content_html'], article_detail['content_html']) + assert_not_in('mpvoice', article_detail['content_html'], article_detail['content_html']) + + # 图片有src属性,无data-src属性 + content_html = BeautifulSoup(article_detail['content_html'], 'lxml') + iframes = content_html.find_all("iframe", src=re.compile(r'http')) + assert_equal(len(iframes), 1, iframes) + for iframe in iframes: + assert_is_none(iframe.attrs.get('data-src')) + if __name__ == '__main__': unittest.main() diff --git a/wechatsogou/api.py b/wechatsogou/api.py index fa85f5e..168febc 100644 --- a/wechatsogou/api.py +++ b/wechatsogou/api.py @@ -2,22 +2,22 @@ from __future__ import absolute_import, unicode_literals, print_function -import re import json +import re import time import requests -from wechatsogou.five import quote from wechatsogou.const import WechatSogouConst -from wechatsogou.request import WechatSogouRequest -from wechatsogou.structuring import WechatSogouStructuring -from wechatsogou.exceptions import WechatSogouRequestsException, WechatSogouVcodeOcrException +from wechatsogou.exceptions import WechatSogouRequestsException, WechatSogouVcodeOcrException, WechatSogouException +from wechatsogou.five import quote from wechatsogou.identify_image import ( ws_cache, identify_image_callback_by_hand, unlock_sogou_callback_example, unlock_weixin_callback_example) +from wechatsogou.request import WechatSogouRequest +from wechatsogou.structuring import WechatSogouStructuring class WechatSogouAPI(object): @@ -41,7 +41,6 @@ def __init__(self, captcha_break_time=1, **kwargs): def __set_cookie(self, suv=None, snuid=None, referer=None): suv = ws_cache.get('suv') if suv is None else suv snuid = ws_cache.get('snuid') if snuid is None else snuid - _headers = {'Cookie': 'SUV={};SNUID={};'.format(suv, snuid)} if referer is not None: _headers['Referer'] = referer @@ -62,7 +61,6 @@ def __get(self, url, session, headers): def __unlock_sogou(self, url, resp, session, unlock_callback=None, identify_image_callback=None): if unlock_callback is None: unlock_callback = unlock_sogou_callback_example - millis = int(round(time.time() * 1000)) r_captcha = session.get('http://weixin.sogou.com/antispider/util/seccode.php?tc={}'.format(millis)) if not r_captcha.ok: @@ -103,7 +101,6 @@ def __get_by_unlock(self, url, referer=None, unlock_platform=None, unlock_callba session = requests.session() resp = self.__get(url, session, headers=self.__set_cookie(referer=referer)) - if 'antispider' in resp.url or '请输入验证码' in resp.text: for i in range(self.captcha_break_times): try: @@ -120,6 +117,41 @@ def __get_by_unlock(self, url, referer=None, unlock_platform=None, unlock_callba return resp + def __hosting_wechat_img(self, content_info, hosting_callback): + """将微信明细中图片托管到云端,同时将html页面中的对应图片替换 + + Parameters + ---------- + content_info : dict 微信文章明细字典 + { + 'content_img_list': [], # 从微信文章解析出的原始图片列表 + 'content_html': '', # 从微信文章解析出文章的内容 + } + hosting_callback : callable + 托管回调函数,传入单个图片链接,返回托管后的图片链接 + + Returns + ------- + dict + { + 'content_img_list': '', # 托管后的图片列表 + 'content_html': '', # 图片链接为托管后的图片链接内容 + } + """ + assert callable(hosting_callback) + + content_img_list = content_info.pop("content_img_list") + content_html = content_info.pop("content_html") + for idx, img_url in enumerate(content_img_list): + hosting_img_url = hosting_callback(img_url) + if not hosting_img_url: + # todo 定义标准异常 + raise Exception() + content_img_list[idx] = hosting_img_url + content_html = content_html.replace(img_url, hosting_img_url) + + return dict(content_img_list=content_img_list, content_html=content_html) + def get_gzh_info(self, wecgat_id_or_name, unlock_callback=None, identify_image_callback=None): """获取公众号微信号 wechatid 的信息 @@ -197,7 +229,6 @@ def search_gzh(self, keyword, page=1, unlock_callback=None, identify_image_callb unlock_platform=self.__unlock_sogou, unlock_callback=unlock_callback, identify_image_callback=identify_image_callback) - return WechatSogouStructuring.get_gzh_by_search(resp.text) def search_article(self, keyword, page=1, timesn=WechatSogouConst.search_article_time.anytime, @@ -381,12 +412,52 @@ def get_gzh_article_by_hot(self, hot_index, page=1, unlock_callback=None, identi resp.encoding = 'utf-8' return WechatSogouStructuring.get_gzh_article_by_hot(resp.text) - def get_article_content(self): + def get_article_content(self, url, del_qqmusic=True, del_mpvoice=True, unlock_callback=None, + identify_image_callback=None, hosting_callback=None): """获取文章原文,避免临时链接失效 - :return: + Parameters + ---------- + url : str or unicode + 原文链接,临时链接 + del_qqmusic: bool + True:微信原文中有插入的qq音乐,则删除 + False:微信源文中有插入的qq音乐,则保留 + del_mpvoice: bool + True:微信原文中有插入的语音消息,则删除 + False:微信源文中有插入的语音消息,则保留 + unlock_callback : callable + 处理 文章明细 的时候出现验证码的函数,参见 unlock_callback_example + identify_image_callback : callable + 处理 文章明细 的时候处理验证码函数,输入验证码二进制数据,输出文字,参见 identify_image_callback_example + hosting_callback: callable + 将微信采集的文章托管到7牛或者阿里云回调函数,输入微信图片源地址,返回托管后地址 + + Returns + ------- + content_html + 原文内容 + content_img_list + 文章中图片列表 + + Raises + ------ + WechatSogouRequestsException """ - pass # TODO 获取文章原文,避免临时链接失效 + + resp = self.__get_by_unlock(url, + unlock_platform=self.__unlock_wechat, + unlock_callback=unlock_callback, + identify_image_callback=identify_image_callback) + + resp.encoding = 'utf-8' + if '链接已过期' in resp.text: + raise WechatSogouException('get_article_content 链接 [{}] 已过期'.format(url)) + content_info = WechatSogouStructuring.get_article_detail(resp.text, del_qqmusic=del_qqmusic, + del_voice=del_mpvoice) + if hosting_callback: + content_info = self.__hosting_wechat_img(content_info, hosting_callback) + return content_info def get_sugg(self, keyword): """获取微信搜狗搜索关键词联想 diff --git a/wechatsogou/identify_image.py b/wechatsogou/identify_image.py index a03510a..33a5358 100644 --- a/wechatsogou/identify_image.py +++ b/wechatsogou/identify_image.py @@ -57,7 +57,6 @@ def unlock_sogou_callback_example(url, req, resp, img, identify_image_callback): """ # no use resp url_quote = url.split('weixin.sogou.com/')[-1] - unlock_url = 'http://weixin.sogou.com/antispider/thank.php' data = { 'c': identify_image_callback(img), diff --git a/wechatsogou/structuring.py b/wechatsogou/structuring.py index f5f12f9..d224044 100644 --- a/wechatsogou/structuring.py +++ b/wechatsogou/structuring.py @@ -2,16 +2,20 @@ from __future__ import absolute_import, unicode_literals, print_function -import re import json +import re +import requests +from bs4 import BeautifulSoup from lxml import etree from lxml.etree import XML -import requests -from wechatsogou.tools import get_elem_text, list_or_empty, replace_html, get_first_of_element +from wechatsogou.exceptions import WechatSogouException from wechatsogou.five import str_to_bytes +from wechatsogou.tools import get_elem_text, list_or_empty, replace_html, get_first_of_element +backgroud_image_p = re.compile('background-image:[ ]+url\(\"([\w\W]+?)\"\)') +js_content = re.compile('js_content.*?>((\s|\S)+)') find_article_json_re = re.compile('var msgList = (.*?)}}]};') get_post_view_perm = re.compile('') @@ -434,3 +438,92 @@ def get_gzh_article_by_hot(text): }) return gzh_article_list + + @staticmethod + def get_article_detail(text, del_qqmusic=True, del_voice=True): + """根据微信文章的临时链接获取明细 + + 1. 获取文本中所有的图片链接列表 + 2. 获取微信文章的html内容页面(去除标题等信息) + + Parameters + ---------- + text : str or unicode + 一篇微信文章的文本 + del_qqmusic: bool + 删除文章中的qq音乐 + del_voice: bool + 删除文章中的语音内容 + + Returns + ------- + dict + { + 'content_html': str # 微信文本内容 + 'content_img_list': list[img_url1, img_url2, ...] # 微信文本中图片列表 + + } + """ + # 1. 获取微信文本content + html_obj = BeautifulSoup(text, "lxml") + content_text = html_obj.find('div', {'class': 'rich_media_content', 'id': 'js_content'}) + + # 2. 删除部分标签 + if del_qqmusic: + qqmusic = content_text.find_all('qqmusic') + for music in qqmusic: + music.parent.decompose() + + if del_voice: + # voice是一个p标签下的mpvoice标签以及class为'js_audio_frame db'的span构成,所以将父标签删除 + voices = content_text.find_all('mpvoice') + for voice in voices: + voice.parent.decompose() + + # 3. 获取所有的图片 [img标签,和style中的background-image] + all_img_set = set() + all_img_element = content_text.find_all('img') + for ele in all_img_element: + # 删除部分属性 + img_url = ele.attrs['data-src'] + del ele.attrs['data-src'] + + if img_url.startswith('//'): + img_url = 'http:{}'.format(img_url) + + ele.attrs['src'] = img_url + + if not img_url.startswith('http'): + raise WechatSogouException('img_url [{}] 不合法'.format(img_url)) + all_img_set.add(img_url) + + backgroud_image = content_text.find_all(style=re.compile("background-image")) + for ele in backgroud_image: + # 删除部分属性 + if ele.attrs.get('data-src'): + del ele.attrs['data-src'] + + if ele.attrs.get('data-wxurl'): + del ele.attrs['data-wxurl'] + img_url = re.findall(backgroud_image_p, str(ele)) + if not img_url: + continue + all_img_set.add(img_url[0]) + + # 4. 处理iframe + all_img_element = content_text.find_all('iframe') + for ele in all_img_element: + # 删除部分属性 + img_url = ele.attrs['data-src'] + del ele.attrs['data-src'] + ele.attrs['src'] = img_url + + # 5. 返回数据 + all_img_list = list(all_img_set) + content_html = content_text.prettify() + # 去除div[id=js_content] + content_html = re.findall(js_content, content_html)[0][0] + return { + 'content_html': content_html, + 'content_img_list': all_img_list + }