0

0

python 写的一个爬虫程序源码分享

高洛峰

高洛峰

发布时间:2017-03-07 16:08:56

|

1896人浏览过

|

来源于php中文网

原创

写爬虫是一项复杂、枯噪、反复的工作,考虑的问题包括采集效率、链路异常处理、数据质量(与站点编码规范关系很大)等。整理自己写一个爬虫程序,单台服务器可以启用1~8个实例同时采集,然后将数据入库。

#-*- coding:utf-8 -*-
#!/usr/local/bin/python
import sys, time, os,string
import mechanize
import urlparse
from BeautifulSoup import BeautifulSoup
import re
import MySQLdb
import logging
import cgi
from optparse import OptionParser
#----------------------------------------------------------------------------#
# Name:    TySpider.py                              #
# Purpose:   WebSite Spider Module                     #
# Author:   刘天斯                                   #
# Email:    liutiansi@gamil.com                         #
# Created:   2010/02/16                              #
# Copyright:  (c) 2010                                #
#----------------------------------------------------------------------------#


"""
|--------------------------------------------------------------------------
| 定义 loging class;
|--------------------------------------------------------------------------
|
| 功能:记录系统相关日志信息。
| 
|
"""
class Pubclilog():
  def __init__(self):
    self.logfile = 'website_log.txt'

  def iniLog(self):
    logger = logging.getLogger()
    filehandler = logging.FileHandler(self.logfile)
    streamhandler = logging.StreamHandler()
    fmt = logging.Formatter('%(asctime)s, %(funcName)s, %(message)s')
    logger.setLevel(logging.DEBUG) 
    logger.addHandler(filehandler) 
    logger.addHandler(streamhandler)
    return [logger,filehandler]


"""
|--------------------------------------------------------------------------
| 定义 tySpider class;
|--------------------------------------------------------------------------
|
| 功能:抓取分类、标题等信息
| 
|
"""
class BaseTySpider:

  #初始化相关成员方法
  def __init__(self,X,log_switch):

    #数据库连接
    self.conn = MySQLdb.connect(db='dbname',host='192.168.0.10', user='dbuser',passwd='SDFlkj934y5jsdgfjh435',charset='utf8')

    #分类及标题页面Community
    self.CLASS_URL = 'http://test.abc.com/aa/CommTopicsPage?'

    #发表回复页
    self.Content_URL = 'http://test.bac.com/aa/CommMsgsPage?'

    #开始comm值
    self.X=X

    #当前comm id取模,方面平均到表
    self.mod=self.X%5

    #Community文件下载页
    self.body=""

    #self.bodySoup对象
    self.soup=None

    #发表回复页下载内容变量
    self.Contentbody=""

    #发表回复页内容self.ContentbodySoup对象
    self.Contentsoup=None

    #日志开关
    self.log_switch=log_switch


  #======================获取名称及分类方法==========================
  def _SpiderClass(self,nextpage=None):
    if nextpage==None:
      FIXED_QUERY = 'cmm='+str(self.X)
    else:
      FIXED_QUERY = nextpage[1:]

    try:
      rd = mechanize.Browser()
      rd.addheaders = [("User-agent", "Tianya/2010 (compatible; MSIE 6.0;Windows NT 5.1)")]
      rd.open(self.CLASS_URL + FIXED_QUERY)
      self.body=rd.response().read()
      #rd=mechanize.Request(self.CLASS_URL + FIXED_QUERY)
      #response = mechanize.urlopen(rd)
      #self.body=response.read()

    except Exception,e:
      if self.log_switch=="on":
        logapp=Pubclilog()
        logger,hdlr = logapp.iniLog()
        logger.info(self.CLASS_URL + FIXED_QUERY+str(e))
        hdlr.flush()
        logger.removeHandler(hdlr)
        return
    self.soup = BeautifulSoup(self.body)
    NextPageObj= self.soup("a", {'class' : re.compile("fs-paging-item fs-paging-next")})
    self.cursor = self.conn.cursor()
    if nextpage==None:
      try:
        Ttag=str(self.soup.table)
        #print Ttag

        """
        ------------------分析结构体-----------------
        

Dunhill

中国 » 人民

""" soupTable=BeautifulSoup(Ttag) #定位到第一个h1标签 tableh1 = soupTable("h1") #print self.X #print "Name:"+tableh1[0].string.strip().encode('utf-8') #处理无类型的 try: #定位到表格中符合规则“^TopByCategory”A链接块,tablea[0]为第一个符合条件的连接文字,tablea[1]... tablea = soupTable("a", {'href' : re.compile("^TopByCategory")}) if tablea[0].string.strip()=="": pass #print "BigCLass:"+tablea[0].string.strip().encode('utf-8') #print "SubClass:"+tablea[1].string.strip().encode('utf-8') except Exception,e: if self.log_switch=="on": logapp=Pubclilog() logger,hdlr = logapp.iniLog() logger.info("[noClassInfo]"+str(self.X)+str(e)) hdlr.flush() logger.removeHandler(hdlr) self.cursor.execute("insert into baname"+str(self.mod)+" values('%d','%d','%s')" %(self.X,-1,tableh1[0].string.strip().encode('utf-8'))) self.conn.commit() self._SpiderTitle() if NextPageObj: NextPageURL=NextPageObj[0]['href'] self._SpiderClass(NextPageURL) return else: return #获取链接二对象的href值 classlink=tablea[1]['href'] par_dict=cgi.parse_qs(urlparse.urlparse(classlink).query) #print "CID:"+par_dict["cid"][0] #print "SubCID:"+par_dict["subcid"][0] #print "---------------------------------------" #插入数据库 self.cursor.execute("insert into class values('%d','%s')" %(int(par_dict["cid"][0]),tablea[0].string.strip().encode('utf-8'))) self.cursor.execute("insert into subclass values('%d','%d','%s')" %(int(par_dict["subcid"][0]),int(par_dict["cid"][0]),tablea[1].string.strip().encode('utf-8'))) self.cursor.execute("insert into baname"+str(self.mod)+" values('%d','%d','%s')" %(self.X,int(par_dict["subcid"][0]),tableh1[0].string.strip().encode('utf-8'))) self.conn.commit() self._SpiderTitle() if NextPageObj: NextPageURL=NextPageObj[0]['href'] self._SpiderClass(NextPageURL) self.body=None self.soup=None Ttag=None soupTable=None table=None table1=None classlink=None par_dict=None except Exception,e: if self.log_switch=="on": logapp=Pubclilog() logger,hdlr = logapp.iniLog() logger.info("[ClassInfo]"+str(self.X)+str(e)) hdlr.flush() logger.removeHandler(hdlr) else: self._SpiderTitle() if NextPageObj: NextPageURL=NextPageObj[0]['href'] self._SpiderClass(NextPageURL) #====================获取标题方法========================= def _SpiderTitle(self): #查找标题表格对象(table) soupTitleTable=self.soup("table", {'class' : "fs-topic-list"}) #查找标题行对象(tr) TitleTr = soupTitleTable[0]("tr", {'onmouseover' : re.compile("^this\.className='fs-row-hover'")}) """ -----------分析结构体--------------

【新人报到】欢迎美国人民加入 0 / 12 @@##@@ 中国人 2-14 """ for CurrTr in TitleTr: try: #初始化置顶及精华状态 Title_starred='N' Title_sticky='N' #获取当前记录的BeautifulSoup对象 soupCurrTr=BeautifulSoup(str(CurrTr)) #BeautifulSoup分析HTML有误,只能通过span的标志数来获取贴子状态,会存在一定误差 #如只有精华时也会当成置顶来处理。 TitleStatus=soupCurrTr("span", {'title' : ""}) TitlePhotoViewer=soupCurrTr("a", {'href' : re.compile("^PhotoViewer")}) if TitlePhotoViewer.__len__()==1: TitlePhotoViewerBool=0 else: TitlePhotoViewerBool=1 if TitleStatus.__len__()==3-TitlePhotoViewerBool: Title_starred='Y' Title_sticky='Y' elif TitleStatus.__len__()==2-TitlePhotoViewerBool: Title_sticky='Y' #获取贴子标题 Title=soupCurrTr.a.next.strip() #获取贴子ID par_dict=cgi.parse_qs(urlparse.urlparse(soupCurrTr.a['href']).query) #获取回复数及浏览器 TitleNum=soupCurrTr("td", {'class' : "fs-topic-name"}) TitleArray=string.split(str(TitleNum[0]),'\n') Title_ReplyNum=string.split(TitleArray[len(TitleArray)-4],'>')[2] Title_ViewNum=string.split(TitleArray[len(TitleArray)-2],'>')[2][:-6] #获取贴子作者 TitleAuthorObj=soupCurrTr("td", {'style' : "padding-left:4px"}) Title_Author=TitleAuthorObj[0].next.next.next.string.strip().encode('utf-8') #获取回复时间 TitleTime=soupCurrTr("td", {'class' : re.compile("^fs-topic-last-mdfy fs-meta")}) """ print "X:"+str(self.X) print "Title_starred:"+Title_starred print "Title_sticky:"+Title_sticky print "Title:"+Title #获取贴子内容连接URL print "Title_link:"+soupCurrTr.a['href'] print "CID:"+par_dict["tid"][0] print "Title_ReplyNum:"+Title_ReplyNum print "Title_ViewNum:"+Title_ViewNum print "Title_Author:"+Title_Author print "TitleTime:"+TitleTime[0].string.strip().encode('utf-8') """ #入库 self.cursor.execute("insert into Title"+str(self.mod)+" values('%s','%d','%s','%d','%d','%s','%s','%s','%s')" %(par_dict["tid"][0], \ self.X,Title,int(Title_ReplyNum),int(Title_ViewNum),Title_starred,Title_sticky, \ Title_Author.decode('utf-8'),TitleTime[0].string.strip().encode('utf-8'))) self.conn.commit() self._SpiderContent(par_dict["tid"][0]) except Exception,e: if self.log_switch=="on": logapp=Pubclilog() logger,hdlr = logapp.iniLog() logger.info("[Title]"+str(self.X)+'-'+par_dict["tid"][0]+'-'+str(e)) hdlr.flush() logger.removeHandler(hdlr) #======================获取发表及回复方法======================= def _SpiderContent(self,ID,nextpage=None): if nextpage==None: FIXED_QUERY = 'cmm='+str(self.X)+'&tid='+ID+'&ref=regulartopics' else: FIXED_QUERY = nextpage[9:] rd = mechanize.Browser() rd.addheaders = [("User-agent", "Tianya/2010 (compatible; MSIE 6.0;Windows NT 5.1)")] rd.open(self.Content_URL + FIXED_QUERY) self.Contentbody=rd.response().read() #rd=mechanize.Request(self.Content_URL + FIXED_QUERY) #response = mechanize.urlopen(rd) #self.Contentbody=response.read() self.Contentsoup = BeautifulSoup(self.Contentbody) NextPageObj= self.Contentsoup("a", {'class' : re.compile("fs-paging-item fs-paging-next")}) try: Tp=self.Contentsoup("p", {'class' : "fs-user-action"}) i=0 for Currp in Tp: if i==0: Ctype='Y' else: Ctype='N' #发表时间 soupCurrp=BeautifulSoup(str(Currp)) PosttimeObj=soupCurrp("span", {'class' : "fs-meta"}) Posttime=PosttimeObj[0].next[1:] Posttime=Posttime[0:-3] #IP地址 IPObj=soupCurrp("a", {'href' : re.compile("CommMsgAddress")}) if IPObj: IP=IPObj[0].next.strip() else: IP='' #发表/回复内容 ContentObj=soupCurrp("p", {'class' :"fs-user-action-body"}) Content=ContentObj[0].renderContents().strip() """ print "ID:"+str(self.X) print "ID:"+ID print "Ctype:"+Ctype print "POSTTIME:"+Posttime print "IP:"+IP print "Content:"+Content """ self.cursor.execute("insert into Content"+str(self.mod)+" values('%s','%d','%s','%s','%s','%s')" %(ID,self.X,Ctype,Posttime,IP,Content.decode('utf-8'))) self.conn.commit() i+=1 except Exception,e: if self.log_switch=="on": logapp=Pubclilog() logger,hdlr = logapp.iniLog() logger.info("[Content]"+str(self.X)+'-'+ID+'-'+str(e)) hdlr.flush() logger.removeHandler(hdlr) #如“下一页”有链接刚继续遍历 if NextPageObj: NextPageURL=NextPageObj[0]['href'] self._SpiderContent(ID,NextPageURL) def __del__(self): try: self.cursor.close() self.conn.close() except Exception,e: pass #遍历comm范围 def initapp(StartValue,EndValue,log_switch): for x in range(StartValue,EndValue): app=BaseTySpider(x,log_switch) app._SpiderClass() app=None if __name__ == "__main__": #定义命令行参数 MSG_USAGE = "TySpider.py [ -s StartNumber EndNumber ] -l [on|off] [-v][-h]" parser = OptionParser(MSG_USAGE) parser.add_option("-s", "--set", nargs=2,action="store", dest="comm_value", type="int", default=False, help="配置名称ID值范围。".decode('utf-8')) parser.add_option("-l", "--log", action="store", dest="log_switch", type="string", default="on", help="错误日志开关".decode('utf-8')) parser.add_option("-v","--version", action="store_true", dest="verbose", help="显示版本信息".decode('utf-8')) opts, args = parser.parse_args() if opts.comm_value: if opts.comm_value[0]>opts.comm_value[1]: print "终止值比起始值还小?" exit(); if opts.log_switch=="on": log_switch="on" else: log_switch="off" initapp(opts.comm_value[0],opts.comm_value[1],log_switch) exit(); if opts.verbose: print "WebSite Scider V1.0 beta." exit;

更多python 写的一个爬虫程序源码分享相关文章请关注PHP中文网!

PHPnow template engine1.0
PHPnow template engine1.0

PHPnow是一个基于PHP的高效的PHP模板引擎,主要对于PHP程序的方面快速开发而设计,这意味着PHP代码与HTML是分开的,让程序员有足够的空间发挥编写程序,让网页设计师轻松维护模板代码,而不需要维护PHP与HTML混合的复杂代码,也不需要掌握PHP技术,从而促进程序员和设计师的快速开发/部署,PHPnow快速且易于维护,重点是永久免费开源

下载
python 写的一个爬虫程序源码分享

相关文章

python速学教程(入门到精通)
python速学教程(入门到精通)

python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

2

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

1

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

1

2026.01.31

golang 循环遍历
golang 循环遍历

本专题整合了golang循环遍历相关教程,阅读专题下面的文章了解更多详细内容。

0

2026.01.31

Golang人工智能合集
Golang人工智能合集

本专题整合了Golang人工智能相关内容,阅读专题下面的文章了解更多详细内容。

1

2026.01.31

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

76

2026.01.31

高干文在线阅读网站大全
高干文在线阅读网站大全

汇集热门1v1高干文免费阅读资源,涵盖都市言情、京味大院、军旅高干等经典题材,情节紧凑、人物鲜明。阅读专题下面的文章了解更多详细内容。

73

2026.01.31

无需付费的漫画app大全
无需付费的漫画app大全

想找真正免费又无套路的漫画App?本合集精选多款永久免费、资源丰富、无广告干扰的优质漫画应用,涵盖国漫、日漫、韩漫及经典老番,满足各类阅读需求。阅读专题下面的文章了解更多详细内容。

67

2026.01.31

漫画免费在线观看地址大全
漫画免费在线观看地址大全

想找免费又资源丰富的漫画网站?本合集精选2025-2026年热门平台,涵盖国漫、日漫、韩漫等多类型作品,支持高清流畅阅读与离线缓存。阅读专题下面的文章了解更多详细内容。

19

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 3.8万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号