betterhexo

折腾categories: toc:true 因为最近找不到什么素材更新博客啦,所以就转头开始折腾博客本身吧。这次对于博客的折腾,主要分为一下方面:

  1. seo优化
  2. 增加统计功能
  3. 优化显示效果
  4. 丰富页面内容

##seo优化
这里主要是添加sitemap被百度等网站收录以及添加robots.txt。参考:
动动手指,不限于NexT主题的Hexo优化(SEO篇)
Hexo的SEO,标签转为关键词,搜索优化
个人博客SEO实践

##增加统计功能
主要是用了不蒜子这个js统计脚本:
不蒜子

##优化显示效果
主要是增加字体大小

football2sms

爬虫

推送足球比分的一个爬虫

标签(空格分隔): 爬虫


github地址在此
主要诱因是爆流量了,然后又刚好最近比赛密集,所以就想做一个能推送当日比赛成绩以及战报的小爬虫了。一开始目标是懂球帝,结果发现竟然是动态内容。后来终于让我找到了网易体育这个对于制作爬虫而言非常良心的网站。好了,既然有了网站我们就可以开始分析啦。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<tr>
<td>11</td>
<td>02:45</td>
<td>完场</td>
<td><span class="c1"><a href="/58/team/7431.html">马尔默</a><img src="http://imgsize.ph.126.net/?imgurl=http://goal.sports.163.com/teamlogo/7431.png_20x20x1.jpg" width="20" height="20" onerror="this.src='http://img1.cache.netease.com/sports/2009/goal/logo/default_team_20.gif'" /></span></td>#主队
<td><span class="c3"><a href="/58/match/stat/2015/1574739.html" target="_blank">1-0</a></span></td>#比分
<td><span class="c2"><img src="http://imgsize.ph.126.net/?imgurl=http://goal.sports.163.com/teamlogo/6457.png_20x20x1.jpg" width="20" height="20" onerror="this.src='http://img1.cache.netease.com/sports/2009/goal/logo/default_team_20.gif'" /><a href="/58/team/6457.html">顿涅茨克矿工</a></span></td>#客队
<td>&nbsp;</td>
<td class="bg2 bg7">
<a href="/58/match/stat/2015/1574739.html" target="_blank">统计</a> | <span class="cur_hand" id="check_1574739_58_2015" style="cursor: pointer;" >查看详细</span> <img src="http://img1.cache.netease.com/sports/2009/goal/slbg33.gif" width="5" height="13" /> |
<a href="http://caipiao.163.com/order/preBet_jczqspfp.html&&t=2325#from=sj1" target="_blank">投注</a>
</td>
</tr>

从这段代码中不难看出。class=’c1’对应的是span标签的正文是主队,class=’c2’对应的则是客队,而class=’c3’对应的则是比分。然后接下来就可以形成代码啦!

1
2
3
4
5
6
7
8
9
10
11
12
def get_bifeng(mytime):
# date = '20151101'
date = mytime
goal_url = 'http://goal.sports.163.com/schedule/' + date + '.html'#构成网址
response = urllib2.urlopen(goal_url)
page = response.read()
soup = BeautifulSoup(page)#构造bs
tag_zhudui = soup.find_all('span', 'c1')
tag_kedui = soup.find_all('span', 'c2')
tag_bifeng = soup.find_all('span', 'c3')
temp_bifeng = []
bifeng = ' '

通过这段代码可以轻松得到主队,客队还有比分的列表。那么如何把三个列表合并并且格式化输出,我用的是比较简单的两个两个合并然后输出的方法,代码如下:

1
2
3
4
5
for (i, j) in zip(tag_zhudui, tag_bifeng):
temp_bifeng.append(i.get_text().encode('utf-8') + ' ' + j.get_text().encode('utf-8') + ' ')
for (i, j) in zip(tag_kedui, temp_bifeng):
bifeng += (j + ' ' + i.get_text().encode('utf-8')+'\n')
return bifeng

这段函数有个缺陷就是偶尔会有当日没有结束的比赛,这就造成了,有主队和客队却没有对应的比分选项,以后再修这个bug。

接下来就是获取战报啦,咱们还是先分析网页的源码:

<tr>
                    <td>11</td>
                    <td>02:45</td>
                    <td>完场</td>
                    <td><span class="c1"><a href="/58/team/6409.html">巴黎圣日耳曼</a><img src="http://imgsize.ph.126.net/?imgurl=http://goal.sports.163.com/teamlogo/6409.png_20x20x1.jpg" width="20" height="20" onerror="this.src='http://img1.cache.netease.com/sports/2009/goal/logo/default_team_20.gif'" /></span></td>
                    <td><span class="c3"><a href="/58/match/stat/2015/1574752.html" target="_blank">0-0</a></span></td>
                    <td><span class="c2"><img src="http://imgsize.ph.126.net/?imgurl=http://goal.sports.163.com/teamlogo/6171.png_20x20x1.jpg" width="20" height="20" onerror="this.src='http://img1.cache.netease.com/sports/2009/goal/logo/default_team_20.gif'" /><a href="/58/team/6171.html">皇家马德里</a></span></td>
                    <td>&nbsp;</td>
                    <td class="bg2 bg7">#战报对应的标签在这里!
                        <a href="/58/match/report/2015/1574752.html" target="_blank">战报</a> | <span class="cur_hand"  id="check_1574752_58_2015" style="cursor: pointer;" >查看详细</span> <img src="http://img1.cache.netease.com/sports/2009/goal/slbg33.gif" width="5" height="13" /> |

不难看出战报对应的标签为td下的class=’bg2 bg7’,然后形成代码:

def get_zhanbao(mytime):
#    date = '20151101'
    date = mytime
    goal_url = 'http://goal.sports.163.com/schedule/' + date + '.html'#构成网址
    response = urllib2.urlopen(goal_url)
    page = response.read()
    soup = BeautifulSoup(page)#构造bs
    tag = soup.find_all(class_='bg2 bg7')#查找对应标签
    zhanbao = []
    mail_content = ''
    for i in tag:
        if i.get_text().encode('utf-8')[7:13] == '战报':#判断关键字段为‘统计’还是‘战报’,这里注意utf-8三个值为一个汉字
            zhanbao.append('http://goal.sports.163.com'+i.find('a').get('href'))#存储所有‘战报’的超链接
#    print zhanbao
    for i in zhanbao:
        response = urllib2.urlopen(i)
        page = response.read()
        soup = BeautifulSoup(page)
        tag = soup.find_all('b')#在战报页面中,‘b’标签(加粗),对应的就是打门,这就是我所需要的啦。
        if tag == '':
            break
        for i in tag:
            mail_content += i.get_text().encode('utf-8')+'|'#构造邮件内容
            print i
#    print mail_content
    return mail_content

然后再写好函数部分,最后加到crontab里面就ok啦,至于邮箱,网上py发邮箱的方法很多,就不再啰嗦啦。

能够改进的地方:

  1. 以后或许考虑直接推送处理好的html页面,这样可以包含更多更直观的数据(这样逼格高许多)
  2. 格式化输出那莫名其妙的空格问题
  3. 发邮件看看能不能一封战报一个邮件,这样最后到短信上的效果会好很多

aliyun

阿里云

阿里云内核更新全过程

标签(空格分隔): 阿里云


九月份的时候突然得知阿里云云翼对大学生超级良心的优惠,算下来一年只需要70,虽然的确配置不咋滴还限制流量,但是毕竟便宜。不过买回来以后真的发觉不知道可以用来干啥,就当了下编程环境,然后跑了下爬虫。实在不甘心啊,这可是两顿鸡公煲的钱!于是打算手动更新内核咯,也为以后自己精简树莓派内核做准备咯。

1.需要准备的材料:
a.阿里云vps
b.最新的linux kernel
c.各种依赖包

2.大概的步骤
a.下载好需要的一切
b.make config
c.make
d.make install

好了,首先就是需要把所有的软件包更新到最新。插一段话,我因为编译比较无聊,所以顺手把阿里云盾卸载了(实在想不出谁会闲着没事搞我的主机,反正我有格盘大法我怕谁啊)。安利下彻底卸载阿里云云盾的方法:

1
2
3
wget http://update.aegis.aliyun.com/download/uninstall.sh
chmod +x uninstall.sh
sh uninstall.sh

我直接执行反正提示什么循环变量出现问题,然后索性就把脚本里执行的命令复制出来,全部执行,最后再看下top,ok!

  1. 首先就是去wget最新的kernel啦,地址在此!。下载好后先用xz -d命令解压,再用tar -xf命令解压,得到内核文件夹。
  2. 理想中的情况应该是用/linux-4.3-rc4/scripts文件架下的extract-ikconfig脚本导出当前的内核配置然后再导入,这样既节省配置时间,而且相对来说也保险一些。然而我死活没有弄清楚该脚本的用法,于是直接make allyesconfig(启用所有的内核功能)。顺便提一下几种配置方法:

    make config #遍历选择编译内核功能
    make allyesconfig #启用内核全部功能
    make allnoconfig #内核功能选项全部为否
    make menuconfig #开启文本菜单选项,对窗口有限制,尽量调大窗口,否则会出错

    #使用此命令需安装gcc和ncurses-devel
    

    make gconfig #依赖GNome桌面环境及GNome的图形开发环境,gtk2
    make kconfig #依赖KDE桌面环境及KDE的图形开发环境,qt

  3. 配置完以后就可以直接make啦,然而竟然提示我scripts/sign-file.c:23:30: fatal error: openssl/opensslv.h: No such file or directory,最后得到的解决方法是apt-get install libssl-dev,果然执行完以后就可以顺利开始编译了。以后如果大家也遇到类似的问题,可以google一下所需要的依赖包或者库文件什么的。
  4. 最后附上的一些小意见。建议用make -j 2这样可以把阿里云的两个核心都用上,适当提高编译速度。还有就是可以安装下screen这个软件,然后输入screen再make,这样就算断开ssh也能继续编译啦。其中在screen命令新建的窗口中ctrl+a+d是隐藏窗口,screen -ls是列出所有窗口列表,screen -r 窗口id是切换窗口。
  5. 之后我就关了putty,让他在后台自己静静地编译了,第二天中午一下看迫不及待地打开一看,发现已经搞定了。于是输入make modules_install || make install,然后再次挂后台。之后直接查看/boot下面有没有编译好的最新镜像就ok啦。然而还有一件奇怪的事情就是虽然编译成功,但是系统仍不用最新的img启动,查看/boot/grub/grub.cfg也发现启动顺序改好了。没办法,使用移除老镜像大法——apt-get remove 你的镜像版本最后终于成功用4.3内核启动了,结尾照例贴图一张晒一晒。此处输入图片的描述

proteus2p

电子

proteus折腾第二步(续)——简单计时器

标签(空格分隔): 电子


proteus2

电子

proteus折腾第二步——数码管动态显示

标签(空格分隔): 电子


定时炸弹怎么能少了计数器,所以点一个led自然是远远不够地。现在我们就让数码管跑起来,折腾这个折腾了一整天也是醉了。我是按照郭天祥开发板的原理图接的锁存器(74h573)和共阴极数码管。注意!7esg-mpx8-ca才是共阴极的,cc是共阳极的。还有一点需要知道的就是锁存器的接法,proteus还是一如既往地帮你接好了gnd和vcc,接下来就是oe和le端了。参考如下这段话:

2、管脚说明:
OE:output_enable,输出使能;
LE:latch_enable,数据锁存使能,latch是锁存的意思;
Dn:第n路输入数据;
On:第n路输出数据;
3、工作原理简述
当OE=1是,无论Dn、LE为何,输出端为高阻态;
当OE=0、LE=0时,输出端保持不变;
当OE=0、LE=1时,输出端数据等于输入端数据;
在实际应用的时候是这样做的:
a. OE=0;
b. 先将数据从单片机的口线上输出到Dn;
c. 再将LE从0->1->0
d. 这时,你所需要输出的数据就锁存在On上了,输入的数据在变化也影响不到输出的数据了;

可以看出,oe端只要长期置零就ok了,所以我们果断连上gnd,然后le端位选接p2^7,段选接p2^6(和郭天祥开发板的接法一样,这样可以直接用他的程序做测试)。至于Dn口的接法需要注意,因为单片机内部P0是没有上拉的,所以得接上拉电阻,我偷懒就直接接P1口啦。最后,对应的数码管段选数组得用这个

unsigned char code dis_code[11]={0xc0,0xf9,0xa4,0xb0, // 0, 1, 2, 3
0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};// 4, 5, 6, 7, 8, 9, off

不然显示不正常。附上我自己改好的程序和最终效果图。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include<reg52.h>
#include<intrins.h>
#define uc unsigned char
sbit duans=P2^6;
sbit weis=P2^7;
unsigned int i,j,num;
uc a,b,c;
unsigned char code table[11]={0xc0,0xf9,0xa4,0xb0, // 0, 1, 2, 3
0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};// 4, 5, 6, 7, 8, 9, off
void main()
{
EA=1;
ET1=1;
TMOD=0x10;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
TR1=1;
while(1)
{
if(num==10)
{
num=0;
P1=table[a];
duans=1;
duans=0;
P1=0xc0; Ãð
weis=1;
weis=0;
a++;
if(a==16)
a=0;
}
}
}void time1() interrupt 3 using 1
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
num++;
}

此处输入图片的描述

proteus1

电子

proteus折腾第一步,led闪起来!

标签(空格分隔): 电子


写实验预习报告的时候突然诞生一个想法,把和追求的女性首次外出玩密室逃脱内破解的定时炸弹复刻一个。然后她过生日的时候送给她,会不会很浪漫。我天生缺乏这方面的东西,就不妄加判断了,总之有想法首先需要去做啊。
首先列下大概的思路:

  1. 需要一个光线或者热源传感器,用来启动数码管开始计时
  2. 需要若干个中断,用来减少时间或者控制一个弹出开关一类的东西
  3. 基本的复位电路是必须的,这样可以反复玩啊
  4. 最好能配合键盘做到可编程,这个只能说是尽力吧

由此推出可能需要的元器件:

  1. 51单片机一个
  2. 晶振
  3. 6位或者8位数码管
  4. 键盘
  5. 插线孔一类的东西

然而我当然不可能一下子就把上面的事情全部搞掂啦。首先需要做的就是在笔记本上测试下我的想法,这时候我就找到了神软proteus。主要是因为网上资料比较多而且这个软件也的确很小。
安装过程还算简单,反正按照步骤走就ok啦。接下来步入正题,如何做一个最基本的led循环闪烁的电路。必须了解的一点就是proteus默认隐藏了vcc和gnd,所以最小系统就不用做啦。

  1. 首先添加必要元件此处输入图片的描述先点击小箭头,再点击p,这样就可以在元件库里面搜索元件啦。这次要用到的是80c51、led-red,搜索完添加即可。此处输入图片的描述
  2. 添加完后,再在设计网格内放置元件并连线此处输入图片的描述
  3. 最后给单片机载入hex文件并仿真。选定单片机,按下ctrl+e,然后选择你编译得到的hex文件。此处输入图片的描述
  4. 最后按下ctrl+f12就可以看到仿真结果啦

附上代码(乱写的,只求有个效果,不严谨之处还望见谅):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<reg52.h>
sbit led=P1^4;
void timer(unsigned char x)
{
int j,k;
for(j=x;j>0;j--)
for(k=10;k>0;k--);
}
void main()
{
while(1)
{
led = 1;
timer(1);
led = 0;
timer(1);
}
}

720n-ipv6

树莓派

720n折腾第二部——ipv6 dhcp以及六维做种

标签(空格分隔): 树莓派


因为sim卡上的拖沓所以只能先去折腾v6啦。openwrt其实已经支持v6很久了,至少获取地址是没问题的,然后ping6 google.com也是有反应的,然而openwrt自带的dhcp v6好像是问题多多。反正我的笔记本每次获取到的都是fe80开头的路由器假地址。然后通过万能的google找到了这样一个知乎回答,这也是最符合我的方案了,无须手动编译6relayed或者更换客户端什么的。不出意外按照教程更改完就能获取到v6地址了。至于transmission的配置,明月永在的固件已经足够傻瓜化了,记得选上dht然后rpc下面的白名单什么的全部不要。最后因为在transmission运行的时候对setting.json的修改是无效的,所以记得重启一次路由器,这样就不会在访问transmission-webui的时候出现403提示啦。

最后晒一下
此处输入图片的描述

openwrt

openwrt

720n正式入手,开始折腾!(系统篇)

标签(空格分隔): 树莓派


最近也很久没更新我的伪技术博了,主要原因是自己。现在救济粮终于到了,于是直接入了个改造好的720n。sam接口和16mflash都让人十分满足啊。
首先遇到的最大问题就是系统,原主任为了好用刷了710n的固件(因为有无线中继),这也就导致刷机困难(如果不改固件头,就只能刷710n的固件)。然后我就手贱刷了官方openwrt for 710n,然后就是没有luci的悲剧故事了。这篇文章就暂时讲下如何在无图形界面的情况下刷网上那些完备固件吧。

1.准备事项:
a.网线
b.合适的固件我用的是明月用在的固件,因为高大全,因为有图形界面,因为支持16m。
c.putty
d.winscp

2.开始动手!
用网线连接720n和电脑,然后把ipv4协议改为自动获取地址。接着用winscp登陆如图
此处输入图片的描述
注意红框中选择的是scp,sftp什么的是不支持的!
接下来需要做的就是把固件传输到/tmp目录下,这个ctrl+c,ctrl+v就搞定了。然后再用putty登陆路由器(不知为何我直接就上去了,并没有telenet,其中用户名是root密码为空)。然后执行

mtd -r write /tmp/xxx.bin firmware

注意必须是绝对路径,虽然我也不知为何。
等刷好重启之后就万事大吉啦,付图一张,感觉openwrt真心各种强大,等到国企是否就可以折腾u盘启动内核,ipv6跳板了呢?期待更新吧!
此处输入图片的描述

hipdacrawler

爬虫

用python爬虫抓取D版帖子正文

标签(空格分隔): 爬虫


其实这次也没有多少创新啦,所用到的东西和上一遍博文的类似。主要还是对网页源码的处理。
变化的有两点:
1.处理帖子列表
2.获取帖子正文

1.处理帖子列表,获得url:

1
2
3
4
5
6
7
8
9
10
11
12
<td class="folder">
<a href="viewthread.php?tid=1686592&amp;extra=page%3D1" title="新窗口打开" target="_blank">
<img src="images/default/folder_new.gif" /></a>
</td>
<td class="icon">
&nbsp;</td>
<th class="subject new">
<label>&nbsp;</label>
<span id="thread_1686592"><a href="viewthread.php?tid=1686592&amp;extra=page%3D1">金庸群侠传X for ios free</a></span>
<img src="images/attachicons/image_s.gif" alt="图片附件" class="attach" />
<span class="threadpages">&nbsp;...<a href="viewthread.php?tid=1686592&amp;extra=page%3D1&amp;page=2">2</a><a href="viewthread.php?tid=1686592&amp;extra=page%3D1&amp;page=3">3</a><a href="viewthread.php?tid=1686592&amp;extra=page%3D1&amp;page=4">4</a><a href="viewthread.php?tid=1686592&amp;extra=page%3D1&amp;page=5">5</a></span>
</th>

从这里可以看出,帖子的url在

1
<a href="viewthread.php?tid=1686592&amp;extra=page%3D1">

这个标签中,但是这个标签重复了两次,一开始我是想用title=”新窗口打开”来处理的,但是没能成功,后面索性加了个计数器,隔行获取就搞掂了。代码如下:

1
2
3
4
5
6
7
8
counter = 2
for i in urls:
if counter%2 == 0:
f = open('temp_'+str(num)+'.txt','a+')
f.write('http://www.hi-pda.com/forum/'+str(i.get('href'))+'\n')
f.close()
counter+=1
print 'get url task '+str(num)+' done!!!'

2.帖子正文的获取:
这个个人感觉比较简单

1
2
3
4
5
6
<div class="t_msgfontfix">
<table cellspacing="0" cellpadding="0"><tr><td class="t_msgfont" id="postmessage_32370210">家里是电信10年老用户,升级到100M光纤了,家里有iphone,ipad,笔记本,小米盒子等需要连接无线路由器,求推荐个符合宽带和使用需求的路由器,目前是几十块的,感觉不行,看动画片都卡</td></tr></table>
</div>

从这里不难看出,获取的关键字是id=”psotmessage_”+任意数字,在beautifulsoup里面直接构造就好了。

1
2
3
4
5
6
7
8
9
10
f = open('temp_'+str(num)+'.txt','r')
for line in f.readlines():
response = opener.open(line)
page = BeautifulSoup(response)
content = page.find_all(id = re.compile('postmessage_'))
for i in content:
fcontent = open('temp_content.txt','a+')
fcontent.write(i.get_text().encode('utf-8'))
fcontent.close()
print 'task '+str(num)+'done!!!'

最终效果:
此处输入图片的描述
此处输入图片的描述
此处输入图片的描述
从图三中也可以看到一个问题,就是那种引用回复的会提高重复率,到时候进行关键词分析必然是会产生影响的,但是现在也没有想出什么好办法去除掉。下一个练手项目就是抓cl的小黄文!!!

bsspider

爬虫

hipda爬虫和关键词统计

标签(空格分隔): 爬虫


忘了是怎么突发奇想,大概还是“闲着也是闲着”又或者“fifa经理人模式不做些什么总是不好的”这一类想法,所以就打算做个hipda相关的爬虫。
可能涉及到的知识
1.通过chrome抓包,并且模拟登陆
2.对cookielib的使用
3.对multiprocessing的使用
4.使用mmeg进行分词,再用jieba进行关键词处理。

首先就是先把必要的库安装好,这里中文分词推荐mmseg,基于c,速度快,支持搜狗细胞词库转化为字典。关键词分析可以用jieba,也可以自己写词频统计再弄个排序什么的。推荐前者,因为有词性支持。

1.通过chrom抓包,模拟登陆,以及保存cookie
这里碰到的第一个问题就是登陆的时候会跳转页面,包不好抓。解决方法也很简单——故意输错用户名。一开始想的是故意输错密码,但是密码是加密的。
此处输入图片的描述
“from data”部分就是需要提交的数据啦。
下面就开始用python构造登陆脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#coding=utf-8
import urllib2
import urllib
import cookielib
import re
import jieba.analyse
from multiprocessing import Pool
from bs4 import BeautifulSoup
def hianalyse(num):
cookie = cookielib.CookieJar()#对cookie进行声明
handler = urllib2.HTTPCookieProcessor(cookie)
opener = urllib2.build_opener(handler)
loginURL = 'http://www.hi-pda.com/forum/logging.php?action=login'
postdata = {
'formhash' : '7fb05e5b',
'referer' : 'index.php',
'loginfield' : 'username',
'username' : 'xxxx',
'password' : 'xxxxxxxx',
'questionid' : '0',
'answer' : '',
'loginsubmit' : 'true',
'cookietime' : '2592000'}
postdata = urllib.urlencode(postdata)
opener.open(loginURL,postdata)#用opener方式打开的网址就都是带cookie了

2.登陆并获取cookie就要开始分析网页源码了

1
http://www.hi-pda.com/forum/forumdisplay.php?fid=2&page=2

看的出来page后面的就是页数。

1
2
3
4
<th class="subject new">
<label>&nbsp;</label>
<span id="thread_1685642"><a href="viewthread.php?tid=1685642&amp;extra=page%3D2">这绝逼是假的,有人配音的。</a></span>
</th>

以viewthread.php?tid=任意数字&extra=page%3D2作为href标签的属性就可以准确定位,于是可以构造表达式

1
viewthread\.php\?tid=\d*&amp;extra=page%3D2

但是我这样构造缺找不到,所以还是老老实实的用viewthread来进行匹配,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
msg = ''#用来储存所有标题
for page_num in range(num*100-99, num*100):#url范围为1-100页
bsURL = 'http://www.hi-pda.com/forum/forumdisplay.php?fid=2&page='+str(page_num)#url结构
response = opener.open(bsURL)
page = BeautifulSoup(response)
tag = page.find_all(href = re.compile('viewthread\.php\?tid=\d*'))
for each_tag in tag:
if is_num_by_except(each_tag.get_text()) == True:
continue
else:
each_tag = each_tag.get_text().encode('utf-8')
msg = msg + each_tag

但是这样会遇到一个问题,就是有时候页码也会被匹配出来,这时候就需要一个函数来判断是否为纯数字

1
2
3
4
5
6
7
def is_num_by_except(num):
try:
int(num)#强制转换为数字类型
return True
except ValueError:
# print "%s ValueError" % num
return False

这样获取标题的部分就算结束了

3.多进程提高抓取效率
一开始是想用多线程方法的,后来发现自己对进程和线程的定义理解错了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
2.关系
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.
相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
3.区别
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
2) 线程的划分尺度小于进程,使得多线程程序的并发性高。
3) 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
4) 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
4.优缺点
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移.

貌似大概的意思就是线程是一件事多个步骤操作,而进程则是多次完成多件事情。其实最重要的原因是threading模块没有看懂啦。

1
2
3
4
5
6
7
if __name__ == '__main__':
p = Pool()#这里括号里面如果有参数就是同时进行参数个任务,如果没有就是进行cpu的核心数个任务
for i in range(10):
p.apply_async(hianalyse,args=(i,))#这里是用来添加进程的
p.close()
p.join()

4.对抓取结果进行词频分析
这里中文分词建议使用mmseg,因为速度快。关键词分析则用jieba,因为方便。

1
2
pip install mmseg
pip install jieba

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#coding=utf-8
from mmseg import seg_txt
import jieba.analyse
f = open('temp.txt','r')#保存标题的文件
f_out = open('temp_out.txt','a+')
for i in seg_txt(f.read()):#用mmseg对其进行分词处理,得到的是个列表
f_out.write(i+'\n')
f.close()
f_out.close()
dic={}
for i in open('temp_out.txt'):#这是网上找来的一个词频统计脚本
array=[]
i=i.strip()
array=i.split()
for j in array:
if not dic.has_key(j):
dic[j]=0
dic[j]+=1
f=open('temp_out_out','w')
for i in dic.keys():
f.write (i+'\t'+str(dic[i])+'\n')
f.close()

如果使用jieba进行关键词提取,只需要一句

1
the_keyword=jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())

sentence是分析对象,topK是出现频率最高的前x个词,withWeight是是否需要返回词频,allowPOS是提取的词性。
这个语句返回的同样是个列表,直接用循环就可以全部输出

1
2
for wd, weight in the_keyword:
print wd, weight#输出关键词和他的词频(前提是withWeight=True)

最后分下一下我对hipda的discovery板块前1000页关键词提取的结果吧
此处输入图片的描述

p.s:
结巴github地址
multiprocessing模块用法