由于博主是一个二流大学的码农,所以想为二流大学量身定做一款APP(当然啦,我只做iOS端的),一来方便学校生活,二来也锻炼一下自己的全栈能力。这个项目的主要功能嘛,无非就是搞个校园新闻首页,偷看学校的免费影视资源,还有就是自动登录上网账号什么的。OK,废话不多说,开始上手。
在本篇中,博主的主要目的是用简单的爬虫把校园网上的影视资源爬取下来并且存储到MySQL中去,以供以后APP服务端使用。为此,我们即将用到的是以下的一些工具:
由于我们需要通过Python连接数据库,因此我们少不了使用MySQLdb模块。唉…Mac装这玩意还真没我想象中轻松啊。
1.安装MySQLdb
在max os x下安装mysql,我们需要使用python访问mysql数据库,需要安装MySQLdb模块,方法如下:
在下面的网址下载mysqldb模块:
解压以后,在解压文件中找到setup_posix.py
找到:
mysql_config.path = “mysql_config”
改为:
mysql_config.path = “/usr/local/mysql/bin/mysql_config”
然后执行:
sudo python setup.py install
安装成功后,在命令行输入python进入python环境,输入import MySQLdb,我的环境中报下面的错误:
import MySQLdb
Traceback (most recent call last):
File “”, line 1, in
File “/Library/Python/2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.11-intel.egg/MySQLdb/init.py”, line 19, in
import _mysql
ImportError: dlopen(/Library/Python/2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.11-intel.egg/_mysql.so, 2): Library not loaded: libmysqlclient.18.dylib
Referenced from: /Library/Python/2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.11-intel.egg/_mysql.so
Reason: unsafe use of relative rpath libmysqlclient.18.dylib in /Library/Python/2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.11-intel.egg/_mysql.so with restricted binary
在10.10的系统环境下只需要:
sudo ln -s /usr/local/mysql/lib/libmysqlclient.18.dylib /usr/lib/libmysqlclient.18.dylib
然而,我的系统已经升级到了10.11,输入上述的指令以后报错:
n: /usr/lib/libmysqlclient.18.dylib: Operation not permitted
出现如下提示的原因是:
OS X 10.11 中System Integrity Protection 的功能,阻止了写入的操作的,默认是开启的,需要关闭。
关闭方式:
重启电脑,开机时按住 cmd + R,进入 Recovery 模式。然后打开终端工具 ,输入命令:csrutil diable,然后再次重启电脑即可。
但是关闭以后,10.11安全性方面的特性就不复存在了,假如既不想关闭 System Intergrity Protection 功能,又想解决Python-MysqlDB的问题,经过Google的帮助,找到了一个解决方法:
sudo install_name_tool -change libmysqlclient.18.dylib \
/usr/local/mysql/lib/libmysqlclient.18.dylib \
/Library/Python/2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.9-intel.egg/_mysql.so
在Python环境下再次import MySQLdb,OK!大功告成,模块已经安装成功了。
在创建数据库之前我们先来看一看校园网视频的下载界面。
好吧,果然丑的那么的理所当然。由于我很懒,所以在构建表的时候我只用上了它的ID,视频名字,视频地址,一级分类和二级分类这些必须的字段。如图:
这样的话数据库端的告一段落,很简单吧(我还在纠结新闻的数据要不要也用这种方式存储,如果后续添加功能我会更新的)。
Python大法好啊!
在构建爬虫之前,我们先来分析一下网页。如图:
看这个貌似有很多的目录层级需要爬取,但是进去之后我笑了:
所有的资源地址都有相同的规律,即http://v8.ccut.edu.cn/article.php?/XXXXX.有了这样的规律以后,就根本不需要翻进去翻出来的爬取数据了,校园网果然有二流学校的作风,连scrapy模块都可以省略了。
新建一个ParserPage.py
既然是要搞爬虫,那么urllib2和re模块肯定是必不可少的了。
先通过urllib2获取页面内容,当然还要经过我们学校隔路的gb2312编码才能看到内容:
html = urllib2.urlopen(url).read().decode(“gb2312”)
然后再定义三个正则表达式,分别从下载界面中获取视频名称、地址和两个分类。
#视频名称
patName = re.compile(r'<font class=bigfont><b>(.*)</b>')
#视频地址
patURL = re.compile(r'href="(.*\.rmvb|.*\.mp4)"')
#视频分类
patList = re.compile(r'<a href="http://v8\.ccut\.edu\.cn/sort\.php\?/\d*">(.*?)</a>')
最后通过findall的方法获取所需要的内容:
resName = re.findall(patName,html)[0]
resURL = re.findall(patURL,html)[0]
resList = re.findall(patList,html)
这是获取一个下载页面的信息,到时候要获取两万多个地址的信息的时候只需要将其抽成一个方法,传入变化的地址参数就可以解析了。
新建一个mysql.py
接下来就是连接数据库,并且保存数据了。引入之前搞了蛮久的MySQLdb。
import MySQLdb
定义好host,port,username,pwd。
host = 'localhost'
port = 3306
user = 'root'
pwd = ''
进行连接并且获取游标,对了不要忘记了设置字符集哦!
def __init__(self):
self.conn = MySQLdb.connect(host=self.host,user=self.user,passwd=self.pwd,db='sy_video',port=self.port,charset='gb2312')
self.conn.set_character_set('gb2312')
self.cur = self.conn.cursor()
定义一个插入数据的方法供外界调用,记得不要忘记了commit。
def insertData(self,id,title,url,leve1,leve2):
try:
sql = 'insert into FreeVideo values(%d,"%s","%s","%s","%s")' % (id,title,url,leve1,leve2)
print(sql)
self.cur.execute(sql)
self.conn.commit()
except MySQLdb.Error,e:
print "Mysql Error %d: %s" % (e.args[0], e.args[1])
最后就是把mysql.py和ParserPage.py整和起来使用了。完整的代码如下:
mysql.py
__author__ = 'Maru'
import MySQLdb
class Mysql:
host = 'localhost'
port = 3306
user = 'root'
pwd = ''
def __init__(self):
self.conn = MySQLdb.connect(host=self.host,user=self.user,passwd=self.pwd,db='sy_video',port=self.port,charset='gb2312')
self.conn.set_character_set('gb2312')
self.cur = self.conn.cursor()
def queryAllData(self):
try:
sql = 'select * from FreeVideo'
self.cur.execute(sql)
except MySQLdb.Error,e:
print "Mysql Error %d: %s" % (e.args[0], e.args[1])
def insertData(self,id,title,url,leve1,leve2):
try:
sql = 'insert into FreeVideo values(%d,"%s","%s","%s","%s")' % (id,title,url,leve1,leve2)
print(sql)
self.cur.execute(sql)
self.conn.commit()
except MySQLdb.Error,e:
print "Mysql Error %d: %s" % (e.args[0], e.args[1])
ParserPage.py
__author__ = 'maru'
import urllib2
import re
import mysql
class ParserPage():
def parserPage(self,url):
try:
html = urllib2.urlopen(url).read().decode("gb2312")
except UnicodeDecodeError,e:
print("UnicodeDecodeError:"+e)
return
except urllib2.URLError,e:
print("URLError"+e)
return
#视频名称
patName = re.compile(r'(.*)')
#视频地址
patURL = re.compile(r'href="(.*\.rmvb|.*\.mp4)"')
#视频分类
patList = re.compile(r'(.*?)')
try:
resName = re.findall(patName,html)[0]
resURL = re.findall(patURL,html)[0]
resList = re.findall(patList,html)
except IndexError,e:
return
return {
"name": resName,
"url": resURL,
"leve1": resList[0],
"leve2": resList[1]
}
if __name__ == "__main__":
index = 500
parser = ParserPage()
db = mysql.Mysql()
while index
晒一晒最终的成果:
代码实现非常的简陋,但是第一个全栈项目还是比较有纪念价值的。附上github地址:
文章浏览阅读135次。Given an array ofn * mmatrix, and a moving matrix window (sizek * k), move the window from top left to botton right at each iteration, find the maximum sum inside the window at each moving.Return..._implement a sliding-window mean filter on an n*n matrix with an m*m window
文章浏览阅读3.3k次。Java生成5个不重复的随机数$package com.sjs.cs;//生成5个不重复的随机数import java.util.Random;public class SjsTest03 {public static void main(String[] args) {//定义生成随机数对象Random r = new Random(); //定义一个5个长度的int类型数组 int arr[] = new int[5]; //给以上数组每一个元素一个初始值,值为-1_5位随机数java
文章浏览阅读3.7k次。使用 git rebase --abort退出 REABASE模式_git 退出rebase
文章浏览阅读568次。linux 内核源码树的建立http://www.cnblogs.com/Jezze/archive/2011/12/23/2299871.html 刚看 O'REILLY 写的《LINUX 设备驱动程序》时。作者一再强调在编写驱动程序时必须 建立内核树。先前的内核只需要有一套内核头文件就够了,但因为2.6的内核模块吆喝内核源码树中的目标文件连接,通过这种方式,可得到一_linux 源码 stage2.c
文章浏览阅读268次。引入fsconst fs = require('fs');用promise读取第一个文件用resolve返回文件内容,用then方法时,value是文件的内容。const p = new Promise(function(resolve, reject) { fs.readFile('第一个.md', (err, data) => { if (err) reject(err); resolve(data); })});链式调用then方法_怎么用then读promise的数据
文章浏览阅读1k次。_百度网盘下载的代码到vscode乱码
文章浏览阅读2.6k次。如果是git的老司机,那么这个问题就很菜了。就是我们日常在本地管理后,推到远程管理,那么有一些文件我们并不想推送到远程,怎么弄?开始天真的自己竟然认为像node_modules这样的文件,git推送的时候是自动忽略的。(当时的想法是,这些文件太大了,git知道不需要)。现在回过头来,才知道多么天真。其实,需要我们自己定义规则,去考虑git需要忽略那些文件,机器再智能也需要人去操作。1、.ignor..._git ignore将index
文章浏览阅读9k次,点赞6次,收藏33次。个人环境是使用matlab2017b该公式计算欧拉角有个要求,必须是3x3的旋转矩阵(尝试过4x4的计算不了)。matlab自带的由旋转矩阵计算欧拉角公式是,rotm2eul(),可以指定旋转顺序,否则默认旋转顺序为ZYX...._matlab旋转矩阵转欧拉角
文章浏览阅读169次。5、服务监控hystrixDashboard5.1、概述除了隔离依赖服务的调用以外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少成功,多少失败等。Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控内容转化成可视化_除了隔离依赖服务的调用以外,hystrix还提供了准实时的调用监控(hystrix dashboard
文章浏览阅读1.1k次。JFinal简介基于JFinal的web项目需要创建一个继承自JFinalConfig类的子类,该类对整个web项目进行配置。JFinalConfig子类需要事项六个抽象方法1.configConstant(…)此方法用来配置JFinal常量值如开发模式常量devMode配置,会输出本次请求的URL、Controller、Method以及请求所携带的参数2.configRoute(…..._jifinal
文章浏览阅读3.7k次。Arthas 命令解析(jvm/thread/stack/heapdump)[Arthas](https://arthas.aliyun.com/doc/index.html)是Alibaba开源的Java诊断工具,`Arthas`支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的`Tab`自动补全功能,进一步方便进行问题的定位和诊断。Arthas 3.0使用OGNL表达式求值库,详见[OGNL表达式官网_arthas分析dump
文章浏览阅读509次。JSP访问数据库_5.mvc中,javabean的生命周期包括()三个阶段