用python。使用第三方库将python 中文文本聚类"中国是一个伟大的国家"执行分词操作。

摘要:20世纪初以来,文本的情感分析在自然语言处理领域成为了研究的热点,吸引了众多学者越来越多的关注。对于中文文本的情感倾向性研究在这样一大环境下也得到了显著的发展。本文主要是基于机器学习方法的中文文本情感分类,主要包括:使用开源的Markup处理程序对XML文件进行分析处理、中科院计算所开源的中文分词处理程序ICTCLAS对文本进行分词处理、去除停用词等文本预处理,在基于向量空间模型VSM的文本表示,使用卡方统计量CHI的进行特征选择,TFIDF权值计算方法进行的特征权值计算,最后使用支持向量机SVM进行中文文本情感的分类。在实验过程中,对比了特征数量的大小对情感分类结果的影响、布尔权值、TF权值和TFIDF权值三种不同计算方法对情感分类结果的影响以及SVM分类器对于不同类型文本数据的分类效果。从整个实验结果来看,TFIDF权值计算相较于其他两种更有利于文本的情感分类。SVM分类器作为文本情感分类器对于不同类型的文本数据,其分类效果不同,但总体上取得了较好的效果。
关键词:中文文本情感分类 &SVM分类器& 特征选择
国内外研究现状
文本情感分类是文本分类中的一个重要分支,也称之为意见挖掘。简而言之,文本的情感分类就是对带有情感色彩的主观性文本进行分析、处理、归纳和推理的过程[1]。情感分类中,按照处理文本的粒度不同,可分为词语短语级、句子级、篇章级等几个研究层次[2]。在此,对词语短语级的情感分类进行详细阐述。在情感分析中可以认为构成篇章的基本单位包括词、短语、和固定搭配,对于它们的褒贬程度的度量是判别文本情感倾向的基础。国外许多学者做了大量研究,其主要研究方法分为基于字典和基于语料库两种。
基于语料库的词语短语级的情感判别主要是根据它们的语法特性,对大规模语料库进行信息挖掘,从而得到统计数据并对其极性做出判断。在研究早期,学者发现由某些连词连接的形容词具有相同或相反的极性,Hatzivassilolou和Mckeown[4]利用大规模语料库华尔街日报中的连接词信息来自动识别形容词的情感倾向,利用聚类算法将它们归属于褒义或贬义的类别集合。Turney和Littman[5]提出了点互信息的方法判别词的褒贬倾向。Dave等[6]从语料中抽取特征集合,通过分析此特征集合和己标记文本的关系来判定词汇的语义倾向。
基于词典的词语短语的情感判别,主要是根据词典WordNet或HowNet中词语间的关联来判别词语的极性。sista等[7]将GI(General Inquirer)和WordNet中的褒义和贬义词作为种子词,得到一个扩展后的较大规模情感词集合,并以此作为分类特征,利用机器学习方法对文本褒贬义进行了自动分类。Faye Baron和Graeme Hirst[8]从文档中抽取倾向性强的搭配作为种子词汇,取得了较好的分类效果。相对于英语,中文的词汇、短语的情感分析研究起步较晚。中科院自动化所的王根等[9]提出了词语倾向性的极坐标方式,并采用均衡化的互信息方法计算了词语倾向性。北京理工大学的李钝博士[10]把短语归结为一个非递归的基本词汇及依存关系的集合,提出了一种基于短语中心词之间依存概率统计分析方法,并将其应用于对短语的倾向性和倾向强度的计算。
存在的问题和挑战
情感分类的应用十分广泛,因此近年来的发展迅速,取得的不小的进步,同时我们也该看到,由于情感分类问题较复杂,不仅仅是单一的文本分类或文本挖掘任务,因而在研究过程中还存在很多问题与挑战。
1)情感语义的机器理解问题
人类的自然语言情感表达十分复杂,特别是网络评论的形式更加灵活多变,要使机器精确的理解文本中的情感内容,不能简单的提取词语作为特征,还必须结合语言学方面的知识,借助于文本上下文和领域相关性对情感语义进行分析处理。
2)特征提取问题
文本分类中一般采用词袋法表示文本的特征,然而由于情感表达中有许多诸如隐喻、反话等复杂的语言形式,且上下相关,因此简单采用词袋法提取特征并进行分析的效果极其有限,如何提取对情感分析具有更大价值的特征依然是一个有待完善的课题。
3)领域依赖
由于情感表达在不同的领域差别较大,所以无论是在有监督的学习方法还是无监督学习方法,情感分类都面临着领域依赖问题。
4)语料库建设问题
情感分类领域,许多研究者自己通过互联网获取语料,并进行人工标注,即使相同领域语料,但语料内容相差较大且标注标本不统一,造成实验结果很难进行比较。特别是在中文的情感研究领域,国内的公开语料库较少,资源匮乏。
基于机器学习的文本分类方法
基于机器学习的情感分类问题,它的处理过程大致可以分为两个部分,一部分是学习过程,另一部分是情感分类过程。其中,学习过程包括训练过程和测试过程,训练过程中对训练集进行训练得到分类器,用其对测试集进行情感分类,将测试的结果反馈给分类器,进一步改进训练方法,生成新的分类器,最后利用最终生成的分类器对新的文本进行情感分类,其基本流程如图1所示。
图1 基于机器学习的文本情感分类流程图
文本预处理
文本的预处理是进行文本情感分类的第一步,预处理结果的好坏直接影响到今后的分析处理能否顺利进行。文本预处理的目的是从文本语料库中规范地提取出主要内容,去除与文本情感分类不相关的信息。对于中文的预处理,其主要操作包括规范编码,过滤非法字符,分词处理,去除停用词等步骤。
1)文件规范编码处理
从网上下载的语料库存储格式可能千差万别,对实验带来很大困扰。所以第一步一般都是对语料库进行数据格式的归一化处理。
2)中文分词处理
中文文本单词之间没有天然的分隔符,因此在提取特征之前,首先要对中文文本进行分词。分词处理能够将连续的汉字序列按照一定的规则重新切分为词或词组。切分好的词或词组将会作为文本的特征用于情感分类分析过程,因此能否高效、正确的对中文进行分词成为中文情感分析的重要任务。中国科学院计算技术研究所专门开发了汉语词法分析系统ICTCLAS(Institute of Computing Technology,ChineseLexical Analysis System)。ICTCLAS的主要功能包括中文分词、词性标注、新词识别、命名实体识别等功能,它的分词性能和分词精度都较高,是目前最受好评的汉语分词开源系统。
3)停用词去除
文本中包含许多助词、虚词等词性的单词以及在文本中经常出现的高频词汇但其本身对情感分类意义不大,这些词汇我们将它们统称为停用词。停用词表的构造一般有两种方式,人工方式或机器自动统计。停用词的存在不但会增加存储空间,而且很可能形成噪声,影响情感分类的精度,因此需要过滤文本中的停用词。
文本表示模型
文本是一种非结构化的数据,由大量字符构成,计算机无法直接处理字符类型的数据,因此需要将普通文本的内容转变为计算机能够读懂的数据形式,即将文本进行形式化表示。本文采用向量空间模型来表示文本。
向量空间模型(VSM)[11]是由salton等人在1975年提出的一个基于统计的文本表示模型,并成功的应用在著名的SMART系统中。向量空间模型可以形式化的表述为,对于给定的文本D=D{t1,w1;t2,w2;…tn,wn}其中ti表示第i个特征项(最小不可分割的语言单位,如字、词、短语),wi表示特征项ti所拥有的权值,n为特征项的总数。每一个文本可以表示为一个向量(w1,w2…wn),wi的计算可以使用布尔权重法,词频权重和TFIDF权重。
向量空间模型对文本的表示效果较好,可以将文档表示成空间向量进行运算,且具有较强的可计算性和可操作性。向量空间模型是文本分类中应用最为广泛的文本形式化模型。向量空间模型的缺点也十分明显,忽略了特征的次序和位置关系,且不考虑文本的长度,不考虑语义联系,认为所有的特征项都是独立的,只考虑文本所属类别的文档中出现特征项的频率,在情感分类的应用中存在一定的局限性。
在对文本进行预处理并对其进行形式化表示后,得到了一个高维稀疏的特征空间,特征的数量可以达到几万维甚至是几十万维,不仅使得运算时间变长,而且会在很大程度上降低分类的准确度。特征选择(Feature Selection)就是从原始的高维特征集合中选择一小部分特征作为分类器的分类特征。特征选择过程需要通过构造好的评估函数对每个特征进行评分,然后按照评分的大小对特征向量进行降序排序,最后选择一定数量的特征作为分类特征集合。目前常用的特征选择方法有文档频率(DF)、信息增益(IG)、统计量(CHI)、期望交叉熵(ECE)和互信息(MI)等,本文采用卡方统计量来进行特征选择,并选取了不同数量的特征进行了对比测试。
卡方统计方法[12]用来衡量特征tj和文档类别Cj之间的统计相关强度,并假设tj和Cj之间符合具有一阶自由度的X2分布。特征相对某类的X2统计值越高,则其含有的信息量越多,与该类的相关性越大。CHI的计算公式如下:
&&&&&&&&&&&&&
其中,tj表示特征项,Ci表示类别,N表示文本总数,A表示包含特征tj,且属于类别Ci的文档数,B表示包含特征tj,但不属于类别Ci的文档数,C表示属于类别Ci但不包含特征tj,的文档数,D表示不属于类别Ci且不包含特征tj的文档数。当有多个类别时,分别计算特征tj对每个类别的CHI,然后取最大值作为特征的CHI值。CHI特征选择方法可以在降低85%以上特征维度的情况下取得较好的分类结果。
特征选择过程中选择了最能代表文本内容的特征向量,但是这些特征对文本分类的影响不尽相同,因此,有必要对经过选择的特征进行加权,对表征能力强的特征赋予较大权重,对具有较弱类别区分能力的特征赋予较小的权重,这样可以有效抑制噪声。特征加权(Feature Weighting)就是对特征集合中每个特征根据其对分类的贡献程度赋予一定权值的过程。常用的特征加权方法有布尔权重,词频权重,TFIDF权重。本文分别使用了这三种权重计算方法,并对三种方法得到的分类结果进行了对比分析。
设文本类别集合D={d1,d2,…,dn},dk∈D(k=1,2,…,n),n为文本总数;类别集合C={c1,c2,…,cm},ci∈C(i=1,2,...,m),特征集合T={t1,t2,…,tn},tj∈T(j=1,2,...,n),m为特征总数;wij表示特征tj在文本dk中的权重。
1)布尔权重(Boolean Weighting)
布尔权重是最简单的权重计算方法,其计算公式如下:
若特征tj,在文本di中出现,则其权重wij为1;若特征tj在文本di中不出现,则其权重wij为0。
2)词频权重(Term Frequency,TF)
词频权重是指用特征在文本中的出现次数作为权重。不同类别的文本集合,特征出现的频率有较大差异,因此特征频率信息可以作为文本分类的重要参考之一。一般情况下,对于一个类别,出现频率较高的特征应该包含更多的类别信息,说明此特征对分类具有重要的意义,以词频作为参考赋予较大权重,反之应该赋予较小权重。TF权重计算公式如下:
其中tfij表示特征tj在类别ci中出现的次数。
词频权重相对于布尔权重,不再是均值权重,而是根据文本集合中特征出现的次数对特征进行加权,从权值函数构造来看有了一定的进步,然而词频权值对高频特征过度依赖,忽略了一些带有大量类别信息的低频特征。
3)TFIDF权重
将特征词频和逆文档频率相结合用于特征权重计算,在实验中取得了较好的效果,因此TFIDF也成为了最经典也是最广泛使用的一种特征权重计算方法。逆文档频率(InverseDocument Frequency,IDF)是以包含特征的文档数为参数构造特征权重函数。其核心思想是:在大多数文档中出现的特征所带有的类别信息相比于在少量文本中出现的特征较少,也就是说,若一个特征同时出现在多个文档中,它所携带的类别信息较少,它的重要程度较低。逆文档频率在计算时常采用对数形式,其计算公式如下:
其中,ni为文本集合中包含特征tj的文本数。
集合次品权重函数就形成了TFIDF权重,计算公式如下:
其中,tfij表示特征tj在文本ci中出现的次数,ni为文本集合中包含特征ti的文本数。
为了消除文本长度对特征权重的影响,要对特征的权重进行归一化处理,归一化后的TFIDF特征权重函数如下:
分类器是文本分类问题中的核心部分,在进行文本分类过程中常用的分类器有朴素贝叶斯分类器(NB),支持向量机(SVM),最大熵分类器(ME),K近邻分类器(KNN)等,本文中主要使用支持向量机来进行分类,用现有的LibSVM完成实际操作,并对book类别、dvd类别和music类别的训练集分别进行了测试,对比测试结果。
支持向量机(Support Vector Machine)是Cortes和Vapnik[13]等人首先提出,它在解决小样本、非线性及高维模式识别中表现出许多优势,并能够推广应用到函数拟合等其他机器学习问题中。其基本思想是首先通过非线性变换将输入空间映射到一个高维特征空间,然后根据核函数在这个新空间中求取最优线性分类平面。将支持向量机应用于文本分类表现尤为突出,其分类的精确率和召回率都较高,且具有较好的稳定性,虽然它在大数据集上的训练收敛速度较慢,需要大量的存储资源和较高的计算能力,但其分隔面模式有效地克服了特征冗余、样本分布以及过拟合等因素的影响,具有较好的泛化能力。
在进行文本分类实验时,需要将文本集合划分为训练集合和测试集合,在进行划分时一般采用K折交叉验证法,将其得到的实验结果的平均值作为实验的最终结果。对结果的评价已经有了许多标准,常用的有查准率、查全率等。
查准率是指分类器判别为ci类别的文本数与实际属于ci类别的文本数的比值,其计算公式如下:
查全率是指实际属于ci类别的文本数与分类器判别为ci类别的文本数的比值,其计算公式如下:
查准率和查全率分别反映分类器不同方面的性能:查准率反映分类器的准确性,查全率反映分类器的完备性。采用准确率还是召回率作为分类器的评价性能取决于实验者所侧重的目标,两个评价标准是互补的,单纯提高其中一个评价标准会导致另一个评价标准的降低。对于一个优良的分类器应该同时具备较高的查准率和查全率。
实验方法与步骤
为了更好的理解情感分类的相关算法与步骤,结合相关论文方法与语料库进行了一系列的实验。实验过程框架图如图2所示,实验步骤如下:
1)&&将训练文本数据文件作为XML文件处理,提取评论文本数据信息;
2)&&对评论文本数据进行中文分词处理与停用词去除处理,并统计词频;
3)&&结合预处理结果、词频信息以及情感标签,使用CHI方法进行特征选择;
4)&&对评论文本进行特征权值计算并归一化权值,使用VSM模型表示文本;
5)&&结合归一化后的特征权值向量,利用支持向量机分类器进行分类器训练;
6)&&对测试文本进行情感分类的学习预测。
图2 中文情感分类实验框架图
结合实验框架图的基础上,针对分类过程中的各个部分,通过大量的实验进行验证。主要包括以下几个方面:
1)&&特征数量的大小对情感分类结果的影响。按照理论情况,选取全部的特
征必然会得到最好的分类效果,但是会导致特征维数的急剧增大,从而导致“维数灾难”,以至后续的分类将会很难进行。故通过实验验证特征数量对分类效果的影响,力求做到能够在不大幅度降低分类效果的基础上,选取一个合适并且便于计算的特征数量。
2)&&布尔权值、TF权值和TFIDF权值三种不同计算方法对情感分类结果的影
响 。从大量的论文中分析得出,TFIDF权值计算方法在情感分类中效果最好,这里通过实验对三种不同的权值计算方法进行验证。
3)&&SVM分类器对于不同类型文本数据的分类效果。不同类型的数据语料由
于其内容以及情感变化的不同,在同时使用SVM分类器的过程中其分类效果可能不同。故采取实验的方法验证不同类型文本数据在使用SVM分类器进行情感分类的效果区别。
&&& 最后,结合上述三个实验验证结果,对给定的测试语料进行情感分类实验。
实验结果及分析
实验数据与程序说明
整个实验的相关算法利用C++在Windows平台下完成,使用ICTCLAS中文分词开源程序、LibSVM以及开源的XML文件处理程序Markup完成。具体实验代码详见附件。
实验使用的数据集分为三类,分别为book、dvd和music三类评论文本数据。三类数据集的情况如表2所示:
表2 实验语料数据情况说明表
特征数量的大小对情感分类影响实验
实验对book类别训练集进行测试,分别使用预处理处理后得到的特征集合的10%,15%与20%作为选取的特征。文本的特征权值计算使用TFIDF方法,使用SVM分类器进行训练集的分类训练。在不同特征数量的情况下,训练集的最优分类率如表3所示:
表3不同特征数量最优分类率表
不同权值计算方法对情感分类结果影响实验
实验对book类别训练集进行测试,分别使用预处理处理后得到的特征集合的10%作为选取的特征,文本的特征权值计算分别使用布尔方法、TF方法和TFIDF方法,使用SVM分类器进行训练集的分类训练。在不同权值计算方法的情况下,训练集的最优分类率如表4所示:
表4不同权值计算方法下最优分类率表
分类器对于不同类型文本数据分类效果实验
实验分别对book类别、dvd类别和music类别训练集进行测试,分别使用预处理处理后得到的特征集合的10%作为选取的特征,文本的特征权值计算使用TFIDF方法,使用SVM分类器进行训练集的分类训练。在不同类型数据情况下,训练集的最优分类率如表5所示:
表5 不同文本数据使用SVM分类最优分类率表
测试文本数据分类实验
结合上述三个实验结果,分别对book类别、dvd类别和music类别测试集进行分类实验。实验过程中使用预处理处理后得到的特征集合的10%作为选取的特征,文本的特征权值计算使用TFIDF方法,使用SVM分类器进行训练集的分类训练。三种不同文本测试数据的分类效果如表6所示:
表6测试文本数据分类结果表
本文主要是对基于机器学习方法的情感文本分类做了初步的研究,
取得了一定的研究成果,但得到的结果还有很大的提升空间,就本文而言,在许多方面还需要进一步的研究和改进。
情感分类是一个具有挑战性的研究课题,其问题更加复杂,同一方法应用于不同语料所产生的结果存在较大差异,本文中只在3个类别的数据集上进行了实验,应将该方法应用于更多的数据集进行对比分析研究。此外,分类器的融合方法还有多种,可以进一步实验其他融合策略对于情感分类性能的影响。
从整个实验结果来看,TFIDF权值计算相较于其他两种更有利于文本的情感分类。SVM分类器作为文本情感分类器对于不同类型的文本数据,其分类效果不同,但总体上取得了较好的效果。
[1]赵妍妍,秦兵,刘挺.文本情感分析[J].软件学报,):.
[2]Huang X J, Zhao J. Sentiment analysis for Chinese text[C].Proceedings oftheCommunications of CCF,).
[3]Picard R W.Affective Computing[M].Cambridge:MIT Press,1997.
[4]Hatzivassiloglou V,Mckeown K R.Predicting the semanticorientation of adjectives[C].Proceedings of the 35thAnnual Meeting of the Association for Computational Linguistics and EighthConference of the European Chapter of the Association for ComputationalLinguistics.Association
for Computational Linguistics,.
[5]Tumey P D,Littman M L.Measuring praise and criticism:Inference of semantic orientation from association[J].ACM Transactionson Information Systems,):315-346.
[6]Dave K,Lawrence S,Pennock D M.Mining the peanut gallery:Opinion extractionand semantic classification of product reviews[C].Proceedingsof the 12th internationalconference on World Wide Web.ACM,8.
[7]Sista S.P,Srinivasan S.H.Polarized lexicon for review classification[C.Proceedings of the International Conference on Artificial Intelligence.2.
[8]Faye B,Graeme H.Collocations as cues to semanticorientation[C].Proceedings of AAAI Spring Symposium onExploring Attitude and Affect in Text,2004.
[9]王根,赵军.中文褒贬义词语倾向性的分析[C].第三届学生计算语言学研讨会论文集..
[10]李钝.基于中文文本的网络内容分层监测研究[D].北京:北京理工大学,2007.
[11]Salton G,Wong A,Yang C S.Avector space model for automatic indexing[J].Communicationsofthe ACM, 1):613-620
[12]Zheng Z,Srihari S N.Text Categorization UsingModified-CHI Feature Selection and Document/TermFrequencies[C].Proceedings of the2002 International Conference On MachineLearningAnd Applications,6.
[13]JoachimsT.Text categorizationwith support vector machines:Learning with many relevant features[C].Proceedingsof the lOth European Conference on Machine Learning.Chemnitz,Germany,2.
版权声明:本文为博主原创文章,未经博主允许不得转载。
本文已收录于以下专栏:
相关文章推荐
机器学习的有概率分类器(probabilistic)
,贝叶斯推理网络(bayesian inference networks) , 决策树分类器(decision tree) ,决策规则分类器(...
原文地址:http://blog.chinaunix.net/uid-446337-id-94440.html
机器学习的有概率分类器(probabilistic)
,贝叶斯推理网络(bay...
????????????????????????????????????????????????????????????????????????????????????????????????????...
情感分析,我研究了也有半年有余了,ACL Anthology上关于情感分析的论文也基本看过了一遍,但是到目前还没有什么成就的。以下是我为一位同学毕业设计写的情感分析方面的综述,引用的论文基本上是ACL...
(1)长度:微博的长度限制在140个字符,相比于传统的评论,长度相差很大,根据收集到的语料统计,平均长度为40个字符;正是因为长度有限制,所以微博中网民的观点更容易理解。
(2)数据易获...
学习如何使用斯坦福CoreNLP Java API来进行情感分析(sentiment analysis)。前几天,我还写了一篇关于如何使用TextBlob API在Python里做情感分析,我已经开发...
二、文本情感分析
文本情感分析,又称意见挖掘(Opinion Mining),是指对带有情感色彩的主观性文本进行分析、处理、归纳和推理的过程;属于计算语言学的范畴,涉及到人工智能、机器学习、数据挖掘...
随着Web2.0技术的出现和发展,互联网上(包括门户网站、电子商务网站、社交网站、音/视频分享网站、论坛、博客、微博等)产生了海量的、由用户发表的对于诸如人物、事件、产品等目标实体的评论信息。例如,下...
之前一直想要做一个文本的可视化:词云,然后在网上搜到的一些制作词云的工具,有些是在线的就没有使用,今天偶然看到python提供的wordcloud库,可以方便制作词云,中英文皆可,赶紧试试,做个笔记,...
Python 自然语言处理
他的最新文章
讲师:吴岸城
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)从零开始写Python爬虫 --- 爬虫应用: requests+django实现微信公众号后台4 months agoDjango和公众号对接:虽然微信有自己的后台自动回复功能,但是由于我要实现某些不可描述的功能,就不能用他自带的功能了,好在微信还是给我们提供了很方便的接口的只需要将微信公众号的后台和我们自己的服务器对接来处理「消息」就成这里我用Django作为后端框架django 是Python上非常成熟的第三方web框架,有着十分强大的功能,与之类似的还有 flask、webpy等.....微信有着自己详细的官方文档来介绍如何接入服务器,地址:我也就不一步一步的说了,最主要说一下需要注意的坑:在微信端配置好服务器之后,微信会以GET的方式给服务器发一段验证消息在服务器端我们需要将这串信息按照规则解码并给微信端返回验证信息,如果对比结果一致那么你的服务器就成功对接上了在对接成功之后,微信后台所收到的信息,都会以xml的格式给你的服务器转发过去,你后端服务器所需要做的就是:接收这段xml处理这段xml返回处理后的xml有一个非常坑的一点是,如果你的服务不能返回符合「微信格式」的xml,微信会尝试连续五次给你的服务器发送同样的消息直到你返回正确的消息,或者return一个'success'字符串项目的生成:首先通过命令行生存我们的django 项目:$ django-admin startproject wx_backends
# 接着生成我们的app
cd wx_backends
python manage.py startapp ss
# 看一下当前目录:
├── manage.py
├── __init__.py
├── admin.py
├── apps.py
├── migrations
└── __init__.py
├── models.py
├── tests.py
└── views.py #视图文件
└── wx_backends
├── __init__.py
├── __pycache__
├── __init__.cpython-36.pyc
└── settings.cpython-36.pyc
├── settings.py
# 项目配置文件
├── urls.py #网址路由文件
└── wsgi.py
4 directories, 14 files
# 配置: settings.py,将app加入其中
INSTALLED_APPS = [
# 配置路由: urls.py
from django.conf.urls import url
from . import views
app_name = 'SS'
urlpatterns = [
url(r'^$', views.wechat, name='wechat'),
视图函数的编写:from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from lxml import etree
from django.utils.encoding import smart_str
import hashlib
import time
from .handle import main_handle
# Create your views here.
# 公众号自定义的token 可以自己设置,是一个校对用的常量
TOKEN = '***************'
# csrf_exempt 标记是为了取消django自带的csrf标记
@csrf_exempt
def wechat(request):
所有的消息都用进过这个函数进行验证处理
微信验证的消息是以GET方式获得的
平时的收发则以POST的方式
if request.method == 'GET':
# 我们来获取微信给我们发送的验证消息
signature = request.GET.get('signature', None)
timestamp = request.GET.get('timestamp', None)
nonce = request.GET.get('nonce', None)
echostr = request.GET.get('echostr', None)
token = TOKEN
# 按照微信的验证要求将token字段timestamp、nonce字段惊醒字典顺序排序
# 将三个参数字符串拼接成一个字符串进行sha1加密
# 获得加密后的字符串可与signature对比,标识该请求来源于微信
tmp_list = [token, timestamp, nonce]
tmp_list.sort()
hashstr = "%s%s%s" % tuple(tmp_list)
hashstr = hashlib.sha1(hashstr.encode('utf-8')).hexdigest()
# 如果得出的结果和微信服务器发来的相同,则将echostr返回去
# 就能成功对接了
if hashstr == signature:
return HttpResponse(echostr)
return HttpResponse('wx_index')
if request.method == 'POST':
# 从微信服务器获得转发来的各种消息
# 这里将获取到的非uicode字符转换为可以处理的字符编码
data = smart_str(request.body)
xml = etree.fromstring(data)
# 在控制台输出一下挑调试信息
print('**********收到的XML***********\n')
print(data)
# 调用我们的handle函数来处理xml
response_xml = main_handle(xml)
return HttpResponse(response_xml)
主处理逻辑的编写:'''
处理自动回复逻辑
每个消息都经过main_handl函数进行处理
replay_rules 是外部资源文件。
用来存储一个符合自动回复规则的字典
from django.template.loader import render_to_string
import time
import random
# 引入自动回复字典文件
from .replay_rules import rules
# 引入外部处理函数
from .ss_invite import get_invite_code
from .qiubai import get_jokes
nav_bar = '''公众号正在开发中...
回复「指南」
即可获得精品文章
回复「爬虫」
即可获得相关文章
回复「段子/来个段子」
即可获新鲜的段子
# 用来计算时间间隔的常量,每次消息传递后更新
global last_time
last_time = 1
def main_handle(xml):
global last_time
# 找到传来的消息事件:
# 如果普通用户发来短信,则event字段不会被捕捉
event = xml.find('Event').text
event = '木有事件发生'
# 找到此次传送的消息信息的类型和内容
msg_type = xml.find('MsgType').text
msg_content = xml.find('Content').text
msg_type = ''
msg_content = ''
# 后台打印一下日志
print('**********收到的数据***********')
print(msg_type, event, '\n文本内容:', msg_content)
# 判断是否是新关注的用户
if event == 'subscribe':
text = '欢迎关注公众号,回复「指南」即可获得精品文章'
return parser_text(xml, text)
# 判断消息类型是否是文本
# 目前只能自动回复文本类型的消息
if msg_type == 'text':
# 当收到的信息在处理规则之中时
if msg_content in rules.keys():
text = rules[msg_content]
return parser_text(xml, text)
# 针对邀请码特殊处理
elif msg_content == '邀请码':
text = get_invite_code()
return parser_text(xml,text)
# 针对段子特殊处理
elif msg_content == '段子' or msg_content == '来个段子':
jokes = get_jokes('/')
text = jokes[random.randint(0,len(jokes))]
return parser_text(xml,text)
# 当不属于规则是,返回一个功能引导菜单
# 获取消息传递的时间
t = int(time.time()) - last_time
last_time = (int(time.time()))
print(last_time)
# 当用户连续发信息的时候,我们不自动回复
return parser_text(xml, text=nav_bar)
return 'success'
return 'success'
def parser_text(xml, text):
处理微信发来的文本数据
返回处理过的xml
print(text)
# 我们反转发件人和收件人的消息
fromUser = xml.find('ToUserName').text
toUser = xml.find('FromUserName').text
# event事件是咩有msg id 的
message_id = xml.find('MsgId').text
message_id = ''
# 我们来构造需要返回的时间戳
nowtime = str(int(time.time()))
context = {
'FromUserName': fromUser,
'ToUserName': toUser,
'Content': text,
'time': nowtime,
'id': message_id,
# 我们来构造需要返回的xml
respose_xml = render_to_string('SS/wx_text.xml', context=context)
return respose_xml
返回的xml模板微信对于返回的xml有着强制的格式要求:所以我们需要构造一个类似的模板:&xml&
&ToUserName&
&![CDATA[{{ ToUserName }}]]&
&/ToUserName&
&FromUserName&
&![CDATA[{{ FromUserName }}]]&
&/FromUserName&
&CreateTime&{{ time }}&/CreateTime&
&![CDATA[text]]&
&/MsgType&
&![CDATA[{{ Content }}]]&
&/Content&
&MsgId&{{ id }}&/MsgId&
由于只是大概的介绍,也不能一下吧django的知识都说出来,大家有兴趣的可以自己去了解学习一下写在最后:其实这篇文章大多和爬虫也没太多的关系硬要说只是我个人将爬虫技术用在了日常的生活中说实在每当这个时候,才觉得非常开心而不是为了学写爬虫,而写爬虫总之大家也多多将自己学习到的技术运用在生活之中吧。说起来,经过一段时间的迷茫和犹豫,我最终决定还是走向「web后端开发」这一条道路大部分原因是我被Django的魅力迷上了吧如果大家想学习如何使用这一强大的web框架这里有很好的教程哦:追梦人物的博客:Pythonzh中文社区: 每天的学习记录都会 同步更新到:微信公众号: findyourownway知乎专栏:blog : Github: 49收藏分享举报文章被以下专栏收录爬墙少年的学习记录。推荐阅读{&debug&:false,&apiRoot&:&&,&paySDK&:&https:\u002F\\u002Fapi\u002Fjs&,&wechatConfigAPI&:&\u002Fapi\u002Fwechat\u002Fjssdkconfig&,&name&:&production&,&instance&:&column&,&tokens&:{&X-XSRF-TOKEN&:null,&X-UDID&:null,&Authorization&:&oauth c3cef7c66aa9e6a1e3160e20&}}{&database&:{&Post&:{&&:{&isPending&:false,&contributes&:[{&sourceColumn&:{&lastUpdated&:,&description&:&&,&permission&:&COLUMN_PUBLIC&,&memberId&:7628740,&contributePermission&:&COLUMN_PUBLIC&,&translatedCommentPermission&:&all&,&canManage&:true,&intro&:&爬墙少年的学习记录。&,&urlToken&:&Ehco-python&,&id&:34946,&imagePath&:&v2-7ca758fd7ad73cf5c6ce41f.jpg&,&slug&:&Ehco-python&,&applyReason&:&0&,&name&:&从零开始写Python爬虫&,&title&:&从零开始写Python爬虫&,&url&:&https:\u002F\\u002FEhco-python&,&commentPermission&:&COLUMN_ALL_CAN_COMMENT&,&canPost&:true,&created&:,&state&:&COLUMN_NORMAL&,&followers&:3646,&avatar&:{&id&:&v2-7ca758fd7ad73cf5c6ce41f&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&activateAuthorRequested&:false,&following&:false,&imageUrl&:&https:\u002F\\u002Fv2-7ca758fd7ad73cf5c6ce41f_l.jpg&,&articlesCount&:31},&state&:&accepted&,&targetPost&:{&titleImage&:&https:\u002F\\u002Fv2-58cf64d8_r.png&,&lastUpdated&:,&imagePath&:&v2-58cf64d8.png&,&permission&:&ARTICLE_PUBLIC&,&topics&:[5,87465],&summary&:&呦呦呦,期末考试这就完结了,从明天开始就要进入忙碌的暑假了,这也会是我最后一个暑假了,要好好珍惜哈,最近因为考试(懒)一直都没有更新,可是我这不是来了嘛。我们到现在也写了不少小爬虫了,可是说实在都是自娱自乐,也没有用到实际的项目中去,这次…&,&copyPermission&:&ARTICLE_COPYABLE&,&translatedCommentPermission&:&all&,&likes&:0,&origAuthorId&:0,&publishedTime&:&T21:22:43+08:00&,&sourceUrl&:&&,&urlToken&:,&id&:3237357,&withContent&:false,&slug&:,&bigTitleImage&:false,&title&:&从零开始写Python爬虫 --- 爬虫应用: requests+django实现微信公众号后台&,&url&:&\u002Fp\u002F&,&commentPermission&:&ARTICLE_ALL_CAN_COMMENT&,&snapshotUrl&:&&,&created&:,&comments&:0,&columnId&:34946,&content&:&&,&parentId&:0,&state&:&ARTICLE_PUBLISHED&,&imageUrl&:&https:\u002F\\u002Fv2-58cf64d8_r.png&,&author&:{&bio&:&蛇语爱好者 公众号findyourownway 提供免费梯子&,&isFollowing&:false,&hash&:&2bdcc138fa81ae767fd71&,&uid&:60,&isOrg&:false,&slug&:&Ehcostuff&,&isFollowed&:false,&description&:&爬墙的少年\n蛇语爱好者&,&name&:&Ehco&,&profileUrl&:&https:\u002F\\u002Fpeople\u002FEhcostuff&,&avatar&:{&id&:&v2-d6cbdcf6166fabdeb573ee45d1031920&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&memberId&:7628740,&excerptTitle&:&&,&voteType&:&ARTICLE_VOTE_CLEAR&},&id&:700878}],&title&:&从零开始写Python爬虫 --- 爬虫应用: requests+django实现微信公众号后台&,&author&:&Ehcostuff&,&content&:&\u003Cblockquote\u003E\u003Cp\u003E呦呦呦,期末考试这就完结了,从明天开始就要进入忙碌的暑假了,这也会是我最后一个暑假了,要好好珍惜哈,最近因为考试(懒)一直都没有更新,可是我这不是来了嘛。\u003C\u002Fp\u003E\u003Cp\u003E我们到现在也写了不少小爬虫了,可是说实在都是自娱自乐,也没有用到实际的项目中去,这次我们就来用爬充和Django实现微信公众号自动回复「段子」的功能。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Ch3\u003E具体效果:\u003C\u002Fh3\u003E\u003Cp\u003E目前功能还比较简陋:\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002Fv2-6becafb8a1b5c21fb1a7e_b.png\& data-rawwidth=\&750\& data-rawheight=\&1334\& class=\&origin_image zh-lightbox-thumb\& width=\&750\& data-original=\&https:\u002F\\u002Fv2-6becafb8a1b5c21fb1a7e_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='750'%20height='1334'&&\u002Fsvg&\& data-rawwidth=\&750\& data-rawheight=\&1334\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&750\& data-original=\&https:\u002F\\u002Fv2-6becafb8a1b5c21fb1a7e_r.png\& data-actualsrc=\&https:\u002F\\u002Fv2-6becafb8a1b5c21fb1a7e_b.png\&\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002Fv2-c4dc3e54ec46c_b.png\& data-rawwidth=\&750\& data-rawheight=\&1334\& class=\&origin_image zh-lightbox-thumb\& width=\&750\& data-original=\&https:\u002F\\u002Fv2-c4dc3e54ec46c_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='750'%20height='1334'&&\u002Fsvg&\& data-rawwidth=\&750\& data-rawheight=\&1334\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&750\& data-original=\&https:\u002F\\u002Fv2-c4dc3e54ec46c_r.png\& data-actualsrc=\&https:\u002F\\u002Fv2-c4dc3e54ec46c_b.png\&\u003E\u003Cbr\u003E\u003Cp\u003E打个小广告,\u003Cbr\u003E欢迎关注我的公众号:findyourownway\u003Cbr\u003E里面会分享一些和「技术相关」的文章~\u003C\u002Fp\u003E\u003Ch3\u003E爬虫的编写:\u003C\u002Fh3\u003E\u003Cp\u003E爬虫的部分十分简单,只是爬取糗百首页的段子,\u003Cbr\u003E一段几十行的脚本就能解决,我就不细说了。\u003Cbr\u003E要是看不太明白,可以回头看看我以前发的文章啦\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-python\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003Erequests\u003C\u002Fspan\u003E\n\u003Cspan class=\&kn\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003Ebs4\u003C\u002Fspan\u003E \u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003EBeautifulSoup\u003C\u002Fspan\u003E\n\n\n\u003Cspan class=\&k\&\u003Edef\u003C\u002Fspan\u003E \u003Cspan class=\&nf\&\u003Eget_html_text\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eurl\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E):\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Etry\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Er\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Erequests\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eget\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eurl\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Etimeout\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E\u003Cspan class=\&mi\&\u003E3\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Er\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eraise_for_status\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E()\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Er\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eencoding\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Er\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eapparent_encoding\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Er\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Etext\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eexcept\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E'something wrong'\u003C\u002Fspan\u003E\n\n\n\u003Cspan class=\&k\&\u003Edef\u003C\u002Fspan\u003E \u003Cspan class=\&nf\&\u003Eget_jokes\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eurl\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E):\u003C\u002Fspan\u003E\n
\u003Cspan class=\&sd\&\u003E'''\u003C\u002Fspan\u003E\n\u003Cspan class=\&sd\&\u003E
返回当前url页面的糗百的\u003C\u002Fspan\u003E\n\u003Cspan class=\&sd\&\u003E
段子作者,主体,热评\u003C\u002Fspan\u003E\n\u003Cspan class=\&sd\&\u003E
返回类型:列表\u003C\u002Fspan\u003E\n\u003Cspan class=\&sd\&\u003E
'''\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Ejoke_list\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E[]\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&n\&\u003Ehtml\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Eget_html_text\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eurl\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Esoup\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003EBeautifulSoup\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Ehtml\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E'lxml'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&n\&\u003Earticles\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Esoup\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Efind_all\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'div'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Eclass_\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'article block untagged mb15'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&k\&\u003Efor\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Earticle\u003C\u002Fspan\u003E \u003Cspan class=\&ow\&\u003Ein\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Earticles\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Ebody\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Earticle\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Efind\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'span'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Etext\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Eauthor\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Earticle\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Efind\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'img'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)[\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'alt'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E]\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Etry\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Ecomment\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Earticle\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Efind\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\n
\u003Cspan class=\&s1\&\u003E'div'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Eclass_\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'main-text'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Econtents\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E[\u003C\u002Fspan\u003E\u003Cspan class=\&mi\&\u003E0\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E]\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Ereplace\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'\u003C\u002Fspan\u003E\u003Cspan class=\&se\&\u003E\\n\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E''\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eexcept\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Ecomment\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E'暂时没有热评'\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&n\&\u003Ejoke\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E'作者:{}\u003C\u002Fspan\u003E\u003Cspan class=\&se\&\u003E\\n\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E{}\u003C\u002Fspan\u003E\u003Cspan class=\&se\&\u003E\\n\\n\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E热评{}'\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eformat\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eauthor\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Ebody\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Ecomment\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Ejoke_list\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eappend\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Ejoke\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&nb\&\u003Elen\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Ejoke_list\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E==\u003C\u002Fspan\u003E\u003Cspan class=\&mi\&\u003E0\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Ejoke_list\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eappend\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'爬虫出现错误,快联系作者去更新吧!'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Ejoke_list\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cbr\u003E\u003Ch3\u003EDjango和公众号对接:\u003C\u002Fh3\u003E\u003Cp\u003E虽然微信有自己的后台自动回复功能,\u003Cbr\u003E但是由于我要实现某些不可描述的功能,\u003Cbr\u003E就不能用他自带的功能了,\u003Cbr\u003E好在微信还是给我们提供了很方便的接口的\u003Cbr\u003E只需要将微信公众号的后台和我们自己的服务器对接来处理「消息」就成\u003C\u002Fp\u003E\u003Cp\u003E这里我用Django作为后端框架\u003C\u002Fp\u003E\u003Cblockquote\u003E\u003Cp\u003Edjango 是Python上非常成熟的第三方web框架,有着十分强大的功能,与之类似的还有 flask、webpy等.....\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003E微信有着自己详细的官方文档来介绍如何接入服务器,\u003Cbr\u003E地址:\u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\u002Fmp.\u002Fwiki%3Ft%3Dresource\u002Fres_main%26id%3Dmp\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E微信公众平台\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Cp\u003E我也就不一步一步的说了,\u003Cbr\u003E最主要说一下需要注意的坑:\u003C\u002Fp\u003E\u003Cp\u003E在微信端配置好服务器之后,\u003Cbr\u003E微信会以\u003Cstrong\u003EGET\u003C\u002Fstrong\u003E的方式给服务器发一段验证消息\u003Cbr\u003E在服务器端我们需要将这串信息按照规则解码\u003Cbr\u003E并给微信端返回验证信息,如果对比结果一致\u003Cbr\u003E那么你的服务器就成功对接上了\u003C\u002Fp\u003E\u003Cp\u003E在对接成功之后,微信后台所收到的信息,\u003Cbr\u003E都会以xml的格式给你的服务器转发过去,\u003Cbr\u003E你后端服务器所需要做的就是:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E接收这段xml\u003C\u002Fli\u003E\u003Cli\u003E处理这段xml\u003C\u002Fli\u003E\u003Cli\u003E返回处理后的xml\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E有一个非常坑的一点是,\u003Cbr\u003E如果你的服务不能返回符合「微信格式」的xml,\u003Cbr\u003E微信会尝试连续五次给你的服务器发送同样的消息\u003Cbr\u003E直到你返回正确的消息,或者return一个'success'字符串\u003C\u002Fp\u003E\u003Ch3\u003E项目的生成:\u003C\u002Fh3\u003E\u003Cp\u003E首先通过命令行生存我们的django 项目:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-python\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&err\&\u003E$\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Edjango\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E-\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eadmin\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Estartproject\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Ewx_backends\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E# 接着生成我们的app\u003C\u002Fspan\u003E\n\u003Cspan class=\&n\&\u003Ecd\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Ewx_backends\u003C\u002Fspan\u003E\n\u003Cspan class=\&n\&\u003Epython\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Emanage\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Epy\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Estartapp\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Ess\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E# 看一下当前目录:\u003C\u002Fspan\u003E\n\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\n\u003Cspan class=\&err\&\u003E├──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Emanage\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Epy\u003C\u002Fspan\u003E\n\u003Cspan class=\&err\&\u003E├──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Ess\u003C\u002Fspan\u003E\n\u003Cspan class=\&err\&\u003E│\u003C\u002Fspan\u003E
\u003Cspan class=\&err\&\u003E├──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003E__init__\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Epy\u003C\u002Fspan\u003E\n\u003Cspan class=\&err\&\u003E│\u003C\u002Fspan\u003E
\u003Cspan class=\&err\&\u003E├──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Eadmin\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Epy\u003C\u002Fspan\u003E\n\u003Cspan class=\&err\&\u003E│\u003C\u002Fspan\u003E
\u003Cspan class=\&err\&\u003E├──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Eapps\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Epy\u003C\u002Fspan\u003E\n\u003Cspan class=\&err\&\u003E│\u003C\u002Fspan\u003E
\u003Cspan class=\&err\&\u003E├──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Emigrations\u003C\u002Fspan\u003E\n\u003Cspan class=\&err\&\u003E│\u003C\u002Fspan\u003E
\u003Cspan class=\&err\&\u003E│\u003C\u002Fspan\u003E
\u003Cspan class=\&err\&\u003E└──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003E__init__\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Epy\u003C\u002Fspan\u003E\n\u003Cspan class=\&err\&\u003E│\u003C\u002Fspan\u003E
\u003Cspan class=\&err\&\u003E├──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Emodels\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Epy\u003C\u002Fspan\u003E\n\u003Cspan class=\&err\&\u003E│\u003C\u002Fspan\u003E
\u003Cspan class=\&err\&\u003E├──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Etests\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Epy\u003C\u002Fspan\u003E\n\u003Cspan class=\&err\&\u003E│\u003C\u002Fspan\u003E
\u003Cspan class=\&err\&\u003E└──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Eviews\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Epy\u003C\u002Fspan\u003E \u003Cspan class=\&c1\&\u003E#视图文件\u003C\u002Fspan\u003E\n\u003Cspan class=\&err\&\u003E└──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Ewx_backends\u003C\u002Fspan\u003E\n
\u003Cspan class=\&err\&\u003E├──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003E__init__\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Epy\u003C\u002Fspan\u003E\n
\u003Cspan class=\&err\&\u003E├──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003E__pycache__\u003C\u002Fspan\u003E\n
\u003Cspan class=\&err\&\u003E│\u003C\u002Fspan\u003E
\u003Cspan class=\&err\&\u003E├──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003E__init__\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Ecpython\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E-\u003C\u002Fspan\u003E\u003Cspan class=\&mf\&\u003E36.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Epyc\u003C\u002Fspan\u003E\n
\u003Cspan class=\&err\&\u003E│\u003C\u002Fspan\u003E
\u003Cspan class=\&err\&\u003E└──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Esettings\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Ecpython\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E-\u003C\u002Fspan\u003E\u003Cspan class=\&mf\&\u003E36.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Epyc\u003C\u002Fspan\u003E\n
\u003Cspan class=\&err\&\u003E├──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Esettings\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Epy\u003C\u002Fspan\u003E
\u003Cspan class=\&c1\&\u003E# 项目配置文件\u003C\u002Fspan\u003E\n
\u003Cspan class=\&err\&\u003E├──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Eurls\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Epy\u003C\u002Fspan\u003E \u003Cspan class=\&c1\&\u003E#网址路由文件\u003C\u002Fspan\u003E\n
\u003Cspan class=\&err\&\u003E└──\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Ewsgi\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Epy\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&mi\&\u003E4\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Edirectories\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&mi\&\u003E14\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Efiles\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E# 配置: settings.py,将app加入其中 \u003C\u002Fspan\u003E\n\u003Cspan class=\&n\&\u003EINSTALLED_APPS\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E[\u003C\u002Fspan\u003E\n
\u003Cspan class=\&s1\&\u003E'SS'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E]\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E# 配置路由: urls.py\u003C\u002Fspan\u003E\n\u003Cspan class=\&kn\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003Edjango.conf.urls\u003C\u002Fspan\u003E \u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Eurl\u003C\u002Fspan\u003E\n\u003Cspan class=\&kn\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003E.\u003C\u002Fspan\u003E \u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Eviews\u003C\u002Fspan\u003E\n\u003Cspan class=\&n\&\u003Eapp_name\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E'SS'\u003C\u002Fspan\u003E\n\u003Cspan class=\&n\&\u003Eurlpatterns\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E[\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Eurl\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003Er'^$'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Eviews\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Ewechat\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Ename\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'wechat'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E),\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E]\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Ch3\u003E视图函数的编写:\u003C\u002Fh3\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-python\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&kn\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003Edjango.http\u003C\u002Fspan\u003E \u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003EHttpResponse\u003C\u002Fspan\u003E\n\u003Cspan class=\&kn\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003Edjango.views.decorators.csrf\u003C\u002Fspan\u003E \u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Ecsrf_exempt\u003C\u002Fspan\u003E\n\u003Cspan class=\&kn\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003Elxml\u003C\u002Fspan\u003E \u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Eetree\u003C\u002Fspan\u003E\n\u003Cspan class=\&kn\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003Edjango.utils.encoding\u003C\u002Fspan\u003E \u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Esmart_str\u003C\u002Fspan\u003E\n\u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003Ehashlib\u003C\u002Fspan\u003E\n\u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003Etime\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&kn\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003E.handle\u003C\u002Fspan\u003E \u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Emain_handle\u003C\u002Fspan\u003E\n\n\n\u003Cspan class=\&c1\&\u003E# Create your views here.\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E# 公众号自定义的token 可以自己设置,是一个校对用的常量\u003C\u002Fspan\u003E\n\u003Cspan class=\&n\&\u003ETOKEN\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E'***************'\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E# csrf_exempt 标记是为了取消django自带的csrf标记\u003C\u002Fspan\u003E\n\u003Cspan class=\&nd\&\u003E@csrf_exempt\u003C\u002Fspan\u003E\n\u003Cspan class=\&k\&\u003Edef\u003C\u002Fspan\u003E \u003Cspan class=\&nf\&\u003Ewechat\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Erequest\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E):\u003C\u002Fspan\u003E\n
\u003Cspan class=\&sd\&\u003E'''\u003C\u002Fspan\u003E\n\u003Cspan class=\&sd\&\u003E
所有的消息都用进过这个函数进行验证处理\u003C\u002Fspan\u003E\n\u003Cspan class=\&sd\&\u003E
微信验证的消息是以GET方式获得的\u003C\u002Fspan\u003E\n\u003Cspan class=\&sd\&\u003E
平时的收发则以POST的方式\u003C\u002Fspan\u003E\n\u003Cspan class=\&sd\&\u003E
'''\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Erequest\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Emethod\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E==\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E'GET'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c1\&\u003E# 我们来获取微信给我们发送的验证消息\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Esignature\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Erequest\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003EGET\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eget\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'signature'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&bp\&\u003ENone\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Etimestamp\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Erequest\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003EGET\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eget\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'timestamp'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&bp\&\u003ENone\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Enonce\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Erequest\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003EGET\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eget\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'nonce'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&bp\&\u003ENone\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Eechostr\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Erequest\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003EGET\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eget\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'echostr'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&bp\&\u003ENone\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Etoken\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003ETOKEN\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&c1\&\u003E# 按照微信的验证要求将token字段timestamp、nonce字段惊醒字典顺序排序\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c1\&\u003E# 将三个参数字符串拼接成一个字符串进行sha1加密\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c1\&\u003E# 获得加密后的字符串可与signature对比,标识该请求来源于微信\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Etmp_list\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E[\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Etoken\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Etimestamp\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Enonce\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E]\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Etmp_list\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Esort\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E()\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Ehashstr\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&\u003C\u002Fspan\u003E\u003Cspan class=\&si\&\u003E%s%s%s\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E%\u003C\u002Fspan\u003E \u003Cspan class=\&nb\&\u003Etuple\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Etmp_list\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Ehashstr\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Ehashlib\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Esha1\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Ehashstr\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eencode\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'utf-8'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E))\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Ehexdigest\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E()\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&c1\&\u003E# 如果得出的结果和微信服务器发来的相同,则将echostr返回去\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c1\&\u003E# 就能成功对接了\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Ehashstr\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E==\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Esignature\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003EHttpResponse\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eechostr\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eelse\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003EHttpResponse\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'wx_index'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Erequest\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Emethod\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E==\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E'POST'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E:\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c1\&\u003E# 从微信服务器获得转发来的各种消息\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&c1\&\u003E# 这里将获取到的非uicode字符转换为可以处理的字符编码\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Edata\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Esmart_str\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Erequest\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Ebody\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Exml\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Eetree\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Efromstring\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Edata\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&c1\&\u003E# 在控制台输出一下挑调试信息\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eprint\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'**********收到的XML***********\u003C\u002Fspan\u003E\u003Cspan class=\&se\&\u003E\\n\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eprint\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Edata\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&c1\&\u003E# 调用我们的handle函数来处理xml\u003C\u002Fspan\u003E\n
\u003Cspan class=\&n\&\u003Eresponse_xml\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Emain_handle\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Exml\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003EHttpResponse\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003Eresponse_xml\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Ch3\u003E主处理逻辑的编写:\u003C\u002Fh3\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-python\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&sd\&\u003E'''\u003C\u002Fspan\u003E\n\u003Cspan class=\&sd\&\u003E处理自动回复逻辑\u003C\u002Fspan\u003E\n\u003Cspan class=\&sd\&\u003E每个消息都经过main_handl函数进行处理\u003C\u002Fspan\u003E\n\u003Cspan class=\&sd\&\u003Ereplay_rules 是外部资源文件。\u003C\u002Fspan\u003E\n\u003Cspan class=\&sd\&\u003E用来存储一个符合自动回复规则的字典\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&sd\&\u003E'''\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&kn\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003Edjango.template.loader\u003C\u002Fspan\u003E \u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Erender_to_string\u003C\u002Fspan\u003E\n\u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003Etime\u003C\u002Fspan\u003E\n\u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003Erandom\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E# 引入自动回复字典文件\u003C\u002Fspan\u003E\n\u003Cspan class=\&kn\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003E.replay_rules\u003C\u002Fspan\u003E \u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Erules\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E# 引入外部处理函数\u003C\u002Fspan\u003E\n\u003Cspan class=\&kn\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003E.ss_invite\u003C\u002Fspan\u003E \u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Eget_invite_code\u003C\u002Fspan\u003E\n\u003Cspan class=\&kn\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&nn\&\u003E.qiubai\u003C\u002Fspan\u003E \u003Cspan class=\&kn\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Eget_jokes\u003C\u002Fspan\u003E\n\n\n\u003Cspan class=\&n\&\u003Enav_bar\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E'''公众号正在开发中...\u003C\u002Fspan\u003E\n\u003Cspan class=\&s1\&\u003E \u003C\u002Fspan\u003E\n\u003Cspan class=\&s1\&\u003E回复「指南」\u003C\u002Fspan\u003E\n\u003Cspan class=\&s1\&\u003E即可获得精品文章\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&s1\&\u003E回复「爬虫」\u003C\u002Fspan\u003E\n\u003Cspan class=\&s1\&\u003E即可获得相关文章\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&s1\&\u003E回复「段子\u002F来个段子」\u003C\u002Fspan\u003E\n\u003Cspan class=\&s1\&\u003E即可获新鲜的段子\u003C\u002Fspan\u003E\n\u003Cs}

我要回帖

更多关于 python中文文本分类器 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信