一个简单的python爬虫程序

本文介绍了作者编写的一个Python爬虫程序,用于抓取特定网站的会议列表信息。程序包括模拟登录、正则表达式解析、JSON编码解码、文件读写以及命令行参数处理等功能。通过爬虫,作者可以获取会议的详细信息并本地存储,以供后续个性化搜索。文章详细阐述了各模块的实现,并分享了代码中的一些技巧和待改进之处。
摘要由CSDN通过智能技术生成

#简介
在每次论文被拒再投的过程中,都需要查询最近的与自己论文相关的会议列表。每到这种情况,我一遍采用的是遍历会伴www.myhuiban.com的网站,然后逐个查看会议,关注的有三点,投稿日期,ccf类别,会议相关内容。

##TODO: 需要加网站的截图,更清晰的说明为什么会有这个需求
思考下,也许自己可以写一个简单的python爬虫程序,将所有的会议列表下载下来,然后在本地建立一个所有会议的索引, 这样就可以个性化的定义搜索了。

昨天下午到今天中午,写了大概400行的python代码,基本完成需求。遇到的主要问题有模拟网站登录,正则表达式搜索, json的编码和解码,文件的读取与写入, 命令行参数相关。

#整体框架
Cookie模块: 负责模拟用户登录并保存cookie以便于下次使用
爬虫模块: 首先爬取会议的第一页的所有会议,并解析下一页的网址,然后逐个爬取下一页的会议列表,对每一个会议,根据其网址爬取其会议的详细信息,并保存到内存字典以及文件中
Json转换模块: 负责将会议字典对象转换为字符串并保存到文件,以及从文件中加载字典创建会议列表
搜索模块: 构造命令行参数,遍历会议进行模式匹配。
#具体模块
##Cookie模块
待爬虫的网址需要用户登录后才可以正常访问会议列表信息,因此需要手动模拟用户登录,并保存cookie,以便于下次访问直接使用cookie访问,而不需要再次登录了。

模拟登录并保存cookie的代码片段

    def requestCookie(self):
        #声明一个MozillaCookieJar对象实例来保存cookie,之后写入文件
        self.cookie = cookielib.MozillaCookieJar(self.filename)
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookie))
        postdata = urllib.urlencode({
                    'LoginForm[email]':'xxxxxxx',
                    'LoginForm[password]':'xxxxxx',
                    'LoginForm[rememberMe]':'0',
                    'LoginForm[rememberMe]':'1',
                    'yt0':'登录'
                })
        loginUrl = 'http://www.myhuiban.com/login'
        #模拟登录,并把cookie保存到变量
        result = opener.open(loginUrl,postdata)
        #保存cookie到cookie.txt中
        self.cookie.save(ignore_discard=True, ignore_expires=True)

上述代码首先创建了MozillaCookie的对象,然后创建了opener,利用它打开连接,它将通过POST请求将用户名和密码发送给服务器。
实用tips:
也许你可能需要爬取其他的需要登录的网页, 它需要POST的数据格式可能就会有变化,如何处理呢? 第一,利用浏览器的自带的开发者工具查看当登录时候POST的数据是什么, 第二,手动构造postdata,利用上面的python代码发起登录请求, 第三,对比浏览器返回的Cookie值与手动模拟登录的请求的Cookie值是否相同。

从文件中直接载入Cookie代码

        self.cookie = cookielib.MozillaCookieJar()
        self.cookie.load(self.filename, ignore_discard=True, ignore_expires=True)
        for item in self.cookie:  
            print 'LoadCookie: Name = '+item.name  
            print 'LoadCookie:Value = '+item.value

通过打印对比一下是否和存储的一致。

Cookie文件加载和网络加载合并
通过以下的代码首先从文件中载入,如果载入不到就从网络中请求,请求完毕后保存到文件。通过这种方式,相当于建立了一个缓存机制,不需要每次都从网路中读取Cookie了。

def getCookie(self):
    if(self.cookie == None):    
        self.loadCookie()
    if(self.cookie == None):
        self.requestCookie()
    return self.cookie

##会议对象
将所有会议保存到会议对象中,需要定义会议对象。根据网页上会议的相关属性,定义如下的会议对象:

class Conference:
    #注意jsonDecoder这个函数的名字必须完全一致,传入的参数名字也必须一致
    def __init__(self, ccf, core, qualis, simple, traditinal, delay, sub, note, conf, place, num, browser, content, rate, id):
        self.ccf = ccf
        self.core = core
        self.qualis = qualis
        self.simple = simple
        self.traditinal = traditinal
        self.delay = delay
        self.sub = sub
        self.note = note
        self.conf = conf
        self.place = place
        self.num = num
        self.browser = browser
        self.content = content
        self.id = id
        self.rate = rate
        
    def setContent(self, content):
        self.content = content
    def setAcceptRate(self, rate):
        self.rate = rate
    def printConf(self):
        print 'CCF CORE QUALIS ShortN Long Delay SubmissionDt Notification Conference Place NumberedHold Nread'
        #print('x=%s, y=%s, z=%s' % (x, y, z))
        print self.ccf, self.core , self.qualis , self.simple , self.traditinal , self.delay , self.sub , self.note , self.conf , self.place , self.num , self.browser
    def printDetailConf(self):
        self.printConf()
        print('Content:')
        print self.content
    def isValid(self):
        return self.id == -1
    def json(self):
        pass
    @staticmethod    
    def createConf(line):
        #u'<td></td><td>c</td><td>b2</td><td>IDEAL</td><td><a target="_blank" href="/conference/535">International Conference on Intelligent Data Engineering and Automated Learning</a></td><td></td><td>2016-05-15</td><td>2016-06-15</td><td>2016-10-12</td><td>Wroclaw, Poland</td><td>17</td><td>3932</td>'
        #CCF	CORE	QUALIS	简称	全称	延期	截稿日期	通知日期	会议日期	会议地点	届数	浏览
        pattern = r'<td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td><a target="_blank" href="(.*?)">(.*)</a></td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td>'
        info = re.findall(pattern, line, re.S)[0]
        
        conf = Conference()
        conf.ccf = info[0]
        conf.core = info[1]
        conf.qualis = info[2]
        conf.simple = info[3]
        conf.id = info[4]
        conf.traditinal = info[5]
        conf.delay = info[6]
        conf.sub = info[7]
        conf.note = info[8]
        conf.conf = info[9]
        conf.place = info[10]
        conf.num = info[11]
        conf.browser = info[12]
        #conf.printConf()
        return conf

此会议对象接收一段html代码,并进行解析,将相应的属性解析出来。

##json相关
考虑到不能每次使用此程序都需要爬取所有的会议列表,因此需要将会议对象转换为字符串保存到文件中。 常用的对象序列化方法之一就是json

于是借用网络上的一份对象和json串的转换代码如下:
特此声明:下面的转换代码非本人所写,copy于网络,链接地址为:http://www.cnblogs.com/coser/archive/2011/12/14/2287739.html

class MyEncoder(json.JSONEncoder):
    def default(self,obj):
        #convert object to a dict
        d = {}
        d['__class__'] = obj.__class__.__name__
        d['__module__'] = obj.__module__
        d.update(obj.__dict__)
        return d
 
class MyDecoder(js
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值