99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀python實現(xiàn)簡易采集爬蟲_python實現(xiàn)爬蟲_網(wǎng)絡(luò)爬蟲 python
python實現(xiàn)簡易采集爬蟲_python實現(xiàn)爬蟲_網(wǎng)絡(luò)爬蟲 python
2016-12-26
收藏

python實現(xiàn)簡易采集爬蟲_python實現(xiàn)爬蟲_網(wǎng)絡(luò)爬蟲 python

#!/usr/bin/python
#-*-coding:utf-8-*-

# 簡易采集爬蟲
# 1.采集Yahoo!Answers,parseData函數(shù)修改一下,可以采集任何網(wǎng)站
# 2.需要sqlite3或者pysqlite支持
# 3.可以在DreamHost.com空間上面運行
# 4.可以修改User-Agent冒充搜索引擎蜘蛛
# 5.可以設(shè)置暫停的時間,控制采集速度
# 6.采集Yahoo會被封IP數(shù)小時,所以這個采集用處不大
# Author: Lukin<mylukin@gmail.com>
# Date : 2008-09-25

# 導(dǎo)入采集需要用到的模塊
import re, sys, time
import httplib, os.path as osp
from urlparse import urlparse
# 使用sqite數(shù)據(jù)庫,為了兼容DreamHost.com的空間,只能這么寫了
try :
import sqlite3 as sqlite
except ImportError:
from pysqlite2 import dbapi2 as sqlite

# 采集速度控制,單位秒
sleep = 0
# 數(shù)據(jù)庫路徑
dbname = ‘./database.db’
# 設(shè)置提交的header頭
headers = {“Accept”: “*/*”,”Referer”: “http://answers.yahoo.com/”,”User-Agent”: “Mozilla/5.0+(compatible;+Googlebot/2.1;++http://www.google.com/bot.html)”}
# 連接服務(wù)器
dl = httplib.HTTPConnection(‘a(chǎn)nswers.yahoo.com’)
# 連接數(shù)據(jù)庫
conn = sqlite.connect(osp.abspath(dbname))

# 創(chuàng)建數(shù)據(jù)庫
def createDatabase():
global conn,dbname;
if osp.isfile(osp.abspath(dbname)) : return
c = conn.cursor()
# 創(chuàng)建url列表存放表
c.execute(”’CREATE TABLE IF NOT EXISTS [collect]([cid] INTEGER PRIMARY KEY,[curl] TEXT,[state] INTEGER DEFAULT ‘0’,UNIQUE([curl]));”’)
c.execute(”’CREATE INDEX IF NOT EXISTS [collect_idx_state] ON [collect]([state]);”’)
# 創(chuàng)建分類表
c.execute(”’CREATE TABLE IF NOT EXISTS [sorts]([sortid] INTEGER PRIMARY KEY,[sortname] TEXT,[sortpath] TEXT,[sortfoot] INTEGER DEFAULT ‘0’,[sortnum] INTEGER DEFAULT ‘0’,UNIQUE([sortpath]));”’)
c.execute(”’CREATE INDEX IF NOT EXISTS [sorts_idx_sortname] ON [sorts]([sortname]);”’)
c.execute(”’CREATE INDEX IF NOT EXISTS [sorts_idx_sortfoot] ON [sorts]([sortfoot]);”’)
# 創(chuàng)建文章表
c.execute(”’CREATE TABLE IF NOT EXISTS [article]([aid] INTEGER PRIMARY KEY,[sortid] INTEGER DEFAULT ‘0’,[hits] INTEGER DEFAULT ‘0’,[title] TEXT,[path] TEXT,[question] TEXT,[banswer] TEXT,[oanswer] TEXT,UNIQUE([path]));”’)
c.execute(”’CREATE INDEX IF NOT EXISTS [article_idx_sortid] ON [article]([sortid]);”’)
# 事物提交
conn.commit()
c.close()

# 執(zhí)行采集
def collect(url=”http://answers.yahoo.com/”):
global dl,error,headers; R = 0
print “GET:”,url
urls = urlparse(url); path = urls[2];
if urls[4]!=” : path += ‘?’ + urls[4]
dl.request(method=”GET”, url=path, headers=headers); rs = dl.getresponse()
if rs.status==200 :
R = parseData(rs.read(),url);
else :
print “3 seconds, try again …”; time.sleep(3)
dl.request(method=”GET”, url=path, headers=headers); rs = dl.getresponse()
if rs.status==200 :
R = parseData(rs.read(),url);
else :
print “3 seconds, try again …”; time.sleep(3)
dl.request(method=”GET”, url=path, headers=headers); rs = dl.getresponse()
if rs.status==200 :
R = parseData(rs.read(),url);
else :
print “Continue to collect …”
R = 3
# 更新記錄
updateOneUrl(url,R)
# 返回結(jié)果
return R

# 處理采集到的數(shù)據(jù)
def parseData(html,url):
global dl,conn; R = 2;
c = conn.cursor()
# 格式化html代碼
format = formatURL(clearBlank(html),url)
# 取出所有的連接
urls = re.findall(r”'(<a[^>]*?href=”([^”]+)”[^>]*?>)|(<a[^>]*?href='([^’]+)'[^>]*?>)”’,format,re.I)
if urls != None :
i = 0
# 循環(huán)所有的連接
for regs in urls :
# 得到一個單一的url
sUrl = en2chr(regs[1].strip())
# 判斷url是否符合規(guī)則,符合,則插入數(shù)據(jù)庫
if re.search(‘http(.*?)/(dir|question)/index(.*?)’,sUrl,re.I) != None :
if re.search(‘http(.*?)/dir/index(.*?)’,sUrl,re.I) != None:
if sUrl.find(‘link=list’) == -1 and sUrl.find(‘link=over’) == -1 :
sUrl+= ‘&link=over’
else:
sUrl = sUrl.replace(‘link=list’,’link=over’)
if sUrl[-11:]==’link=mailto’ : continue
try :
c.execute(‘INSERT INTO [collect]([curl])VALUES(?);’,(sUrl,))
i = i + 1
except sqlite.IntegrityError :
pass
if i>0 : print “Message: %d get a new URL.” % (i,)

# 截取數(shù)據(jù)
if re.search(‘http(.*)/question/index(.*)’,url,re.I) != None :
sortfoot = 0
# 自動創(chuàng)建分類和分類關(guān)系
guide = sect(format,'<ol id=”yan-breadcrumbs”>’,'</ol>’,'(<li>(.*?)Home(.*?)</li>)’)
aGuide = re.findall(‘<a[^>]*href=”[^”]*”[^>]*>(.*?)</a>’,guide,re.I)
if aGuide != None :
sortname = “”
for sortname in aGuide :
sortname = sortname.strip()
sortpath = en2path(sortname)
# 查詢分類是否存在
c.execute(‘SELECT [sortid],[sortname] FROM [sorts] WHERE [sortpath]=? LIMIT 0,1;’,(sortpath,))
row = c.fetchone();
# 分類不存在,添加分類
if row==None :
c.execute(‘INSERT INTO [sorts]([sortname],[sortpath],[sortfoot])VALUES(?,?,?);’,(sortname,sortpath,sortfoot))
sortfoot = c.lastrowid
else:
sortfoot = row[0]
# 標題
title = sect(format,'<h1 class=”subject”>’,'</h1>’)
# 最佳答案
BestAnswer = sect(format,'(<h2><span>Best Answer</span>(.*?)</h2>(.*?)<div class=”content”>)’,'(</div>)’)
# 最佳答案不存在,則不采集
if BestAnswer != None :
# 文章路徑
path = en2path(sortname + ‘-‘ + title.strip())
# 問題
adddata = sect(format,'<div class=”additional-details”>’,'</div>’)
content = sect(format,'(<h1 class=”subject”>(.*?)<div class=”content”>)’,'(</div>)’)
if adddata != None : content += ‘<br/>’ + adddata
# 其他回答
OtherAnswer = ”
for regs in re.findall(‘<div class=”qa-container”>(.+?)<div class=”utils-container”>’,format):
if regs.find(‘<h2>’) == -1 and regs.find(‘</h2>’) == -1 :
a1 = sect(regs,'<div class=”content”>’,'</div>’)
a2 = sect(regs,'<div class=”reference”>’,'</div>’)
OtherAnswer+= ‘<div class=”oAnswer”>’ + a1
if a2 != None : OtherAnswer+= ‘<div class=”reference”>’ + a2 + ‘</div>’
OtherAnswer+= ‘</div>’

# 判斷采集成功
if title != None and content != None :
# 將數(shù)據(jù)寫入到數(shù)據(jù)
try :
c.execute(‘INSERT INTO [article]([sortid],[title],[path],[question],[banswer],[oanswer])VALUES(?,?,?,?,?,?);’,(sortfoot,title,path,content,BestAnswer,OtherAnswer))
print “Message:%s.html” % (path,)
R = 1
except sqlite.IntegrityError :
pass
# 提交寫入數(shù)據(jù)庫
conn.commit(); c.close()
return R

# 取得一條URL
def getOneUrl():
global conn; c = conn.cursor()
c.execute(‘SELECT [curl] FROM [collect] WHERE [state] IN(0,3) LIMIT 0,1;’)
row = c.fetchone(); c.close()
if row==None : return “”
return row[0].encode(‘utf-8’)

# 更新一條記錄的狀態(tài)
def updateOneUrl(url,state):
global conn; c = conn.cursor()
c.execute(‘UPDATE [collect] SET [state]=? WHERE [curl]=?;’,(state,url))
conn.commit(); c.close()

# 清除html代碼里的多余空格
def clearBlank(html):
if len(html) == 0 : return ”
html = re.sub(‘\r|\n|\t’,”,html)
while html.find(” “)!=-1 or html.find(‘&nbsp;’)!=-1 :
html = html.replace(‘&nbsp;’,’ ‘).replace(‘ ‘,’ ‘)
return html

# 格式化url
def formatURL(html,url):
urls = re.findall(”'(<a[^>]*?href=”([^”]+)”[^>]*?>)|(<a[^>]*?href='([^’]+)'[^>]*?>)”’,html,re.I)
if urls == None : return html
for regs in urls :
html = html.replace(regs[0],matchURL(regs[0],url))
return html

# 格式化單個url
def matchURL(tag,url):
urls = re.findall(”'(.*)(src|href)=(.+?)( |/>|>).*|(.*)url\(([^\)]+)\)”’,tag,re.I)
if urls == None :
return tag
else :
if urls[0][5] == ” :
urlQuote = urls[0][2]
else:
urlQuote = urls[0][5]

if len(urlQuote) > 0 :
cUrl = re.sub(”'[‘”]”’,”,urlQuote)
else :
return tag

urls = urlparse(url); scheme = urls[0];
if scheme!=” : scheme+=’://’
host = urls[1]; host = scheme + host
if len(host)==0 : return tag
path = osp.dirname(urls[2]);
if path==’/’ : path = ”;
if cUrl.find(“#”)!=-1 : cUrl = cUrl[:cUrl.find(“#”)]
# 判斷類型
if re.search(”’^(http|https|ftp):(//|\\\\)(([\w/\\\+\-~`@:%])+\.)+([\w/\\\.\=\?\+\-~`@’:!%#]|(&amp;)|&)+”’,cUrl,re.I) != None :
# http開頭的url類型要跳過
return tag
elif cUrl[:1] == ‘/’ :
# 絕對路徑
cUrl = host + cUrl
elif cUrl[:3]==’../’ :
# 相對路徑
while cUrl[:3]==’../’ :
cUrl = cUrl[3:]
if len(path) > 0 :
path = osp.dirname(path)
elif cUrl[:2]==’./’ :
cUrl = host + path + cUrl[1:]
elif cUrl.lower()[:7]==’mailto:’ or cUrl.lower()[:11]==’javascript:’ :
return tag
else :
cUrl = host + path + ‘/’ + cUrl
R = tag.replace(urlQuote,'”‘ + cUrl + ‘”‘)
return R

# html代碼截取函數(shù)
def sect(html,start,end,cls=”):
if len(html)==0 : return ;
# 正則表達式截取
if start[:1]==chr(40) and start[-1:]==chr(41) and end[:1]==chr(40) and end[-1:]==chr(41) :
reHTML = re.search(start + ‘(.*?)’ + end,html,re.I)
if reHTML == None : return
reHTML = reHTML.group()
intStart = re.search(start,reHTML,re.I).end()
intEnd = re.search(end,reHTML,re.I).start()
R = reHTML[intStart:intEnd]
# 字符串截取
else :
# 取得開始字符串的位置
intStart = html.lower().find(start.lower())
# 如果搜索不到開始字符串,則直接返回空
if intStart == -1 : return
# 取得結(jié)束字符串的位置
intEnd = html[intStart+len(start):].lower().find(end.lower())
# 如果搜索不到結(jié)束字符串,也返回為空
if intEnd == -1 : return
# 開始和結(jié)束字符串都有了,可以開始截取了
R = html[intStart+len(start):intStart+intEnd+len(start)]
# 清理內(nèi)容
if cls != ” :
R = clear(R,cls)
# 返回截取的字符
return R

# 正則清除
def clear(html,regexs):
if regexs == ” : return html
for regex in regexs.split(chr(10)):
regex = regex.strip()
if regex != ” :
if regex[:1]==chr(40) and regex[-1:]==chr(41):
html = re.sub(regex,”,html,re.I|re.S)
else :
html = html.replace(regex,”)
return html

# 格式化為路徑
def en2path(enStr):
return re.sub(‘[\W]+’,’-‘,en2chr(enStr),re.I|re.U).strip(‘-‘)

# 替換實體為正常字符
def en2chr(enStr):
return enStr.replace(‘&amp;’,’&’)

# ————————————- 開始執(zhí)行程序 ——————————————-

# 首先創(chuàng)建數(shù)據(jù)庫
createDatabase()

# 開始采集
loops = 0
while True:
if loops>0 :
url = getOneUrl()
if url == “” :
loops = 0
else :
loops = collect(url)
else :
loops = collect()
# 暫停
time.sleep(sleep)
if loops==0 : break

# 關(guān)閉HTTP連接
dl.close()
# 退出程序
sys.exit()


數(shù)據(jù)分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個參數(shù)驗證碼對象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗服務(wù)器是否宕機 new_captcha: data.new_captcha, // 用于宕機時表示是新驗證碼的宕機 product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計時完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }