【前言】
# 本腳本用來爬取jd的頁面:http://list.jd.com/list.html?cat=737,794,870到
# ......http://list.jd.com/list.html?cat=737,794,870&page=11&JL=6_0_0的所有html的内容和圖檔。
# 本腳本僅用于技術交流,請勿用于其他用途
# by River
# qq : 179621252
# Date : 2014-12-02 19:00:00
【需求說明】
以京東為示例,爬取頁面的,擷取頁面中得資料:記錄到data.txt;擷取頁面中得圖檔,儲存下來。
1、list的url如下

2、商品詳情頁的url如下:
【技術說明】
使用了python的以下庫
import os#檢查檔案是否存在等
from HTMLParser import HTMLParser#用于解析html的庫,有坑:如果2.6的python,可能悲劇
import httplib,re#發起http請求
import sys,json,datetime,bisect#使用了二分快速查找
from urlparse import urlparse#解析url,分析出url的各部分功能
from threading import Thread#使用多線程
import socket #設定httplib逾時時間
【代碼邏輯說明】
1、run(擷取最終要的結果)
2、parseListpageurl:傳回list的總共的頁面數量
3、judgelist:判斷該list是否已經爬取完畢了,第一個list中的所有url、最後list的所有url都爬取完畢了,那麼久說明list的所有page爬取完畢了(實際上是一種弱校驗)
4、getfinalurl_content:如果list沒爬取完畢,每個list爬取,解析list中得每個html(判斷html是否爬取過),獲得内容和img
【坑說明】
1、需要設定逾時時間,和重試,否則爬取一個url卡住的時候,整個線程都悲劇了。
2、有編碼的坑,如果頁面是gb2312的編碼,需要轉換為utf-8的編碼:httprestmp.decode('gbk').encode('utf-8')
3、parser.feed的内容,如果存在一些特殊字元,可能需要替換,否則解析出來會莫名不對
4、圖檔儲存,根據url擷取前面兩個數字,儲存。以免一個目錄下儲存了過多的圖檔。
【執行結果】
1、console輸出
2、data.txt存儲解析出來的内容
3、judegurl.txt(儲存已經爬取過的url)
4、圖檔(下載下傳的圖檔)
【代碼詳情】
# -*- coding: utf-8 -*-
__author__ = 'River'
# 本腳本用來爬取jd的頁面:http://list.jd.com/list.html?cat=737,794,870到
# ......http://list.jd.com/list.html?cat=737,794,870&page=11&JL=6_0_0的所有html的内容和圖檔。
# 本腳本僅用于技術交流,請勿用于其他用途
# by River
# qq : 179621252
# Date : 2014-12-02 19:00:00
import os#建立檔案
from HTMLParser import HTMLParser#用于解析html的庫,有坑:如果2.6的python,可能悲劇
import httplib,re#發起http請求
import sys,json,datetime,bisect#使用了二分快速查找
from urlparse import urlparse#解析url,分析出url的各部分功能
from threading import Thread#使用多線程
import socket #設定httplib逾時時間
#定義一個ListPageParser,用于解析ListPage,如http://list.jd.com/list.html?cat=737,794,870
#htmlparser的使用簡介
#定義intt方法:需要使用到得屬性
#定義handle_starttag,處理你想分析的tag的具體操作
#定義handle_data,遇到你定義的情況,擷取相應标簽的data
#定義你擷取最終傳回的各種資料
class ListPageParser(HTMLParser):
def __init__(self):
self.handledtags=['a']
self.processing=None
self.flag=''
self.link=''
self.setlinks=set()##該list頁面中包含的每個商品的url,定義為set,主要是為了使用其特性:去重
self.pageNo=1
self.alldata=[]
self.lasturl=""#指的最後一頁的url如<a href="http://list.jd.com/list.html?cat=737%2C794%2C798&page=10&JL=6_0_0" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >10</a>
HTMLParser.__init__(self)
def handle_starttag(self, tag, attrs):
pattern = re.compile(r'^[0-9]{2,}')
pattern2=re.compile(r'^http:\/\/item.jd.com\/\d{1,10}.html$')#取出link
pattern3=re.compile(r'^http:\/\/list.jd.com\/list.html\?cat=\d{0,9}%2C\d{0,9}%2C\d{0,9}&page=*')#取出link
#attrs是屬性的list,每個屬性(包含key,value)又是一個元組
#<a target="_blank" href="http://item.jd.com/1258277.html" target="_blank" rel="external nofollow" οnclick="log("search","list",window.location.href,798,5,1258277,2,1,1,2,A)">創維酷開(coocaa) K50J 50英寸八核智能wifi網絡安卓平闆液晶電視(黑色)<font style="color: #ff0000;" name="1258277" class="adwords"></font></a>
#已上為例子:判斷了該list的長度為3(其他的a标簽就被過濾了)
if tag in self.handledtags and len(attrs)==3 :#非常關鍵的是,找出你想的url和不想要的url的差別
#print "debug:attrs",attrs
self.flag=''
self.data=''
self.processing=tag
for target,href in attrs:#非常關鍵的是,找出你想的url和不想要的url的差別
if pattern2.match(href):#再加一層判斷,如果比對上pattern2,說明是我們想要的url
self.setlinks.add(href)
else:
pass
#怎樣擷取list中最後一頁的url?分析吧:<a href="http://list.jd.com/list.html?cat=737%2C794%2C798&page=10&JL=6_0_0" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >10</a>
#1、長度為1
#2,href是由規則的:cat=737%2C794%2C798&page=10&JL=6_0_0,是以,以下代碼就出來了
if tag in self.handledtags and len(attrs)==1 :
self.flag=''
self.data=''
self.processing=tag
for href,url in attrs:#非常關鍵的是,找出你想的url和不想要的url的差別
#print 'debug:attrs',attrs
if pattern3.match(url):
#print 'debug:url',url
self.lasturl=url
else:
pass
def handle_data(self, data):
if self.processing:#去掉空格
pass#其實這裡我們根本沒使用擷取到得data,就pass把
else:
pass
def handle_endtag(self, tag):
if tag==self.processing:
self.processing=None
def getlinks(self):
return self.setlinks
def getlasturl(self):
return self.lasturl
#定義一個FinallPageParser,用于解析最終的html頁面,如http://item.jd.com/1258277.html
#FinallPageParser的定義過程參考上個parser,關鍵是怎樣分析頁面,最終寫出代碼,并且驗證,這裡就不詳細說了
class FinallPageParser(HTMLParser):
def __init__(self):
self.handledtags=['div','h1','strong','a','del','div','img','li','span','tbody','tr','th','td','i']
self.processing=None
self.title=''
self.jdprice=''
self.refprice=''
self.partimgs_show=set()#展示圖檔
self.partimgs=set()#詳情圖檔
self.partdetail={}#商品詳情,參數等
self.specification=[]#規格參數
self.typeOrsize=set()#尺碼和類型
self.div=''
self.flag={}
self.flag['refprice']=''
self.flag['title']=''
self.flag['jdprice']=''
self.flag['typeOrsize']=''
self.flag['partimgs']=''
self.flag['partdetail']=''
self.flag['specification']=''
self.flag['typeOrsize']=''
self.link=''
self.partslinks={}
HTMLParser.__init__(self)
def handle_starttag(self, tag, attrs):
self.titleflag=''
self.flag['refprice']=''
self.flag['title']=''
self.flag['jdprice']=''
self.flag['typeOrsize']=''
self.flag['partimgs']=''
self.flag['partdetail']=''
self.flag['specification']=''
self.flag['typeOrsize']=''
if tag in self.handledtags:
self.data=''
self.processing=tag
if tag=='div':
for key,value in attrs:
self.div=value# 取出div的name,判斷是否是所需要的圖檔等元素
if tag=='i':
self.flag['typeOrsize']='match'
if tag=='a' and len(attrs)==2:
tmpflag=""
for key,value in attrs:
if key=='href' and re.search(r'^http:\/\/item.jd.com\/[0-9]{1,10}.html$',value):
tmpflag="first"
if key=='title' and value!="":
tmpflag=tmpflag+"second"
if tmpflag== "firstsecond":
self.flag['typeOrsize']='match'
if tag=='h1':
self.flag['title']='match'
if tag=='strong' and len(attrs)==2:
for tmpclass,id in attrs:
if id=='jd-price':
self.flag['jdprice']='match'
if tag=='del':
self.flag['refprice']='match'
if tag=='li':
self.flag['partdetail']='match'
if tag=='th' or tag=='tr' or tag=='td' :#++++++++############################################879498.html td中有br的隻取到第一個,需要把<br/>喜歡為“”
self.flag['specification']='match'
if tag=='img' :
imgtmp_flag=''
imgtmp=''
for key,value in attrs:
if re.search(r'^http://img.*jpg|^http://img.*gif|^http://img.*png',str(value)) and (key=='src' or key=='data-lazyload'):
imgtmp=value
if key== 'width':############可能還有logo
if re.search(r'^\d{1,9}$',value):
if int(value)<=160:
imgtmp_flag='no'
break
if self.div=="spec-items" and imgtmp!='':
imgtmp=re.compile("/n5/").sub("/n1/",imgtmp)
self.partimgs_show.add(imgtmp)
elif imgtmp_flag!='no' and imgtmp!='':
self.partimgs.add(imgtmp)#
def handle_data(self, data):
if self.processing:
self.data+=data
if self.flag['title']=='match':#擷取成功
self.title=data
if self.flag['jdprice']=='match':
self.jdprice=data.strip()
if self.flag['typeOrsize']=='match':
self.typeOrsize.add(data.strip())
if self.flag['refprice']=='match':
self.refprice=data.strip()
if self.flag['partdetail']=='match' and re.search(r':',data):#擷取成功
keytmp=data.split(":")[0].strip()
valuetmp=data.split(":")[1].strip()
self.partdetail[keytmp]=valuetmp
if self.flag['specification']=='match' and data.strip() != '' and data.strip()!='主體':
self.specification.append(data.strip())
else:
pass
def handle_endtag(self, tag):
if tag==self.processing:
self.processing=None
def getdata(self):
return {'title':self.title,'partimgs_show':self.partimgs_show,'jdprice':self.jdprice,'refprice':self.refprice,'partimgs':self.partimgs,'partdetail':self.partdetail,'specification':self.specification,'typeOrsize':self.typeOrsize}
#定義方法httpread,用于發起http的get請求,傳回http的擷取内容
#這也是代碼抽象的結果,如若不抽象這塊代碼出來,後續你回發現很多重複的寫這塊代碼
def httpread(host,url,headers):
httprestmp=''
try:
conn = httplib.HTTPConnection(host)
conn.request('GET',url,None,headers)
httpres = conn.getresponse()
httprestmp=httpres.read()
except Exception,e:
conn = httplib.HTTPConnection(host)
conn.request('GET',url,None,headers)
httpres = conn.getresponse()
httprestmp=httpres.read()
print e
finally:
if conn:
conn.close()
return httprestmp
#定義方法sendhttp,調用httpread,擷取結果并替換編碼(gbk換為utf-8),并儲存到檔案中(以免下次再去下載下傳頁面,這樣就節省了時間)
#
def sendhttp(url,host,savefile):
#定義http頭部,很多網站對于你不攜帶User-Agent及Referer等情況,是不允許你爬取。
#具體的http的頭部有些啥資訊,你可以看chrome,右鍵審查元素,點選network,點選其中一個連結,檢視request header
headers = {"Host":host,
"Origin":"http://www.jd.com/",
"Referer":"http://www.jd.com/",
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"Accept": "text/html;q=0.9,p_w_picpath/webp,*/*;q=0.8",
"User-Agent":"Mozilla/3.0 AppleWebKit/537.36 (KHTML,Gecko) Chrome/3.0.w4.",
"Cookie":"__utmz=qwer2434.1403499.1.1.utmcsr=www.jd.com|utmccn=(refrral)|utmcmd=rferral|utmcct=/order/getnfo.action; _pst=xx89; pin=x9; unick=jaa; cshi3.com=D6045EA24A6FB9; _tp=sdyuew8r9e7r9oxr3245%3D%3D; user-key=1754; cn=0; ipLocation=%u7F0C; ipLoc97; areaId=1; mt_ext2%3a%27d; aview=6770.106|68|5479.665|675.735|6767.100|6757.13730|6ee.9ty711|1649.10440; atw=65.15.325.24353.-4|188.3424.-10|22; __j34|72.2234; __jdc=2343423; __jdve|-; __jdu=3434"
}
httprestmp=''
try:
httprestmp=httpread(host,url,headers)
if httprestmp=='':#
httprestmp=httpread(host,url,headers)
if httprestmp=='':#重試2次
httprestmp=httpread(host,url,headers)
except Exception,e:
try:
httprestmp=httpread(host,url,headers)
if httprestmp=='':#
httprestmp=httpread(host,url,headers)
if httprestmp=='':#重試2次
httprestmp=httpread(host,url,headers)
except Exception,e:
print e
print e
if re.search(r'charset=gb2312',httprestmp):#如果是gb2312得編碼,就要轉碼為utf-8(因為全局都使用了utf-8)
httprestmp.replace("charset=gb2312",'charset=utf-8')
try:
httprestmp=httprestmp.decode('gbk').encode('utf-8')#有可能轉碼失敗,是以要加上try
except Exception,e:#如果html編碼本來就是utf8或者轉換編碼出錯的時候,就啥都不做,就用原始内容
print e
try:
with open(savefile, 'w') as file_object:
file_object.write(httprestmp)
file_object.flush()
except Exception,e:
print e
return httprestmp
#list的頁面的解析方法
def parseListpageurl(listpageurl):
urlobj=urlparse(listpageurl)
if urlobj.query:
geturl=urlobj.path+"?"+urlobj.query
else:
geturl=urlobj.path
htmlfile="html/list"+geturl
if not os.path.exists(htmlfile):
httpresult=sendhttp(geturl,urlobj.hostname,htmlfile)
with open(htmlfile) as file:
htmlcontent=file.read()
parser= ListPageParser()#聲明一個解析對象
#http://list.jd.com/list.html?cat=737%2C794%2C870&page=11&JL=6_0_0,是以這裡需要把'amp;'去掉
parser.feed(htmlcontent.replace('amp;',''))#将html的内容feed進去
#print 'debug:htmlcontent',htmlcontent
finalparseurl=parser.getlinks()#然後get資料即可
lastpageurl=parser.getlasturl()
urlobj_lastpageurl=urlparse(lastpageurl)
#print 'debug:urlobj_lastpageurl',urlobj_lastpageurl
totalPageNo='0'
#print urlobj
if re.search(r'&',urlobj_lastpageurl.query):
try:
totalPageNo=urlobj_lastpageurl.query.split("&")[1].split("=")[1]#獲得總共有多少頁
except Exception,e:
print "lastpageurl:"+str(lastpageurl)
print e
parseListpageurl_rult={'finalparseurls':finalparseurl,'totalPageNo':totalPageNo}
if parseListpageurl_rult['finalparseurls'] !="" and parseListpageurl_rult['totalPageNo']!='':
print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+",parse listpageurl succ:"+listpageurl
else:
print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+",parse listpageurl fail:"+listpageurl
return parseListpageurl_rult
#最終的html頁面的解析方法:會使用到html得解析器FinallPageParser
def parseFinallyurl(finallyurl):
urlobj=urlparse(finallyurl)
geturl=urlobj.path
htmlfiledir="html/finally/"+geturl.split('/')[1][0:2]
if not os.path.exists(htmlfiledir):
try:
os.makedirs(htmlfiledir)
except Exception,e:
print e
htmlfile=htmlfiledir+geturl
if not os.path.exists(htmlfile):
httpresult=sendhttp(geturl,urlobj.hostname,htmlfile)
if httpresult:
print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+",sent http request succ,Finallyurl:"+finallyurl
else:
print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+",sent http request fail,Finallyurl:"+finallyurl
with open(htmlfile) as file:
htmlcontent=file.read()
parser= FinallPageParser()
##htmmparser遇到/>就表示tag結尾,是以必須替換,遇到<br/>替換為BRBR,否則會解析失敗
htmlcontent=re.compile('<br/>').sub('BRBR',htmlcontent)
parser.feed(htmlcontent)
finalparseurl=parser.getdata()
if finalparseurl:
print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+",parse finalparseurl succ:"+finallyurl
else:
print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+",parse finalparseurl fail:"+finallyurl
return finalparseurl
#擷取圖檔的方法
def getimg(imgdir,imgurl):
imgobj=urlparse(imgurl)
getimgurl=imgobj.path
imgtmppathlist=getimgurl.split('/')
imgname=imgtmppathlist[len(imgtmppathlist)-1]
if not os.path.exists(imgdir):
try:
os.makedirs(imgdir)
except Exception,e:
print e
savefile=imgdir+"/"+imgname
if not os.path.exists(savefile):
sendhttp_rult=sendhttp(getimgurl,imgobj.hostname,savefile)
if sendhttp_rult:
print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+",sent http request succ,getimg:"+imgurl
else:
print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+",sent http request fail,getimg:"+imgurl
else:
pass
#擷取價格
def getprice(pricedir,priceurl):
priceobj=urlparse(priceurl)
getpriceurl=priceobj.path+"?"+priceobj.query
pricename="price"
if not os.path.exists(pricedir):
try:
os.makedirs(pricedir)
except Exception,e:
print e
savefile=pricedir+"/"+pricename
if not os.path.exists(savefile):
sendhttp_rult=sendhttp(getpriceurl,priceobj.hostname,savefile)
if sendhttp_rult:
print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+",sent http request succ,getprice:"+priceurl
else:
print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+",sent http request fail,getprice:"+priceurl
else:
pass
with open(savefile) as file:
price_content=file.read()
price_content=re.compile('cnp\\(\\[|\\]\\);').sub('',price_content)
price_dic={"id":"0","p":"0","m":"0"}
if re.search(r':',price_content):
try:
price_dic=json.loads(price_content)#以免資料格式不對悲劇
except Exception,e:
print e
return {"jdprice":price_dic['p'],'refprice':price_dic['m']}
#擷取最後頁面的具體内容
def getfinalurl_content(partlists,listpageurl,finalparseurl):
parseFinallyurl_rult=parseFinallyurl(finalparseurl)
htmlname_tmp=urlparse(finalparseurl).path
imgtopdir_tmp="img/"+htmlname_tmp.split('/')[1][0:2]
imgdir=imgtopdir_tmp+htmlname_tmp+"/introduction"
imgshowdir=imgtopdir_tmp+htmlname_tmp+"/show"
partdetail_tmp=""
for imgurl in parseFinallyurl_rult['partimgs']:#擷取商品介紹的圖檔
getimg(imgdir,imgurl)
for imgshowurl in parseFinallyurl_rult['partimgs_show']:#擷取展示圖檔
getimg(imgshowdir,imgshowurl)
for key in parseFinallyurl_rult['partdetail'].keys():
partdetail_tmp=partdetail_tmp+key+"$$"+parseFinallyurl_rult['partdetail'][key]+","#商品介紹
specification_tmp=""
i=0
for specification_var in parseFinallyurl_rult["specification"]:#規格參數
if i==0:
str_slip=""
elif(i%2==0 and i!=0 ):
str_slip=","
else:
str_slip="$$"
specification_tmp=specification_tmp+str_slip+specification_var
i=i+1
typeOrsize_tmp=""
for typeOrsize_var in parseFinallyurl_rult['typeOrsize']:
typeOrsize_tmp=typeOrsize_tmp+","+typeOrsize_var
priceurl="http://p.3.cn/prices/get?skuid=J_"+htmlname_tmp.split('/')[1].split('.')[0]+"&type=1&area=6_309_312&callback=cnp"
pricedir="price/"+htmlname_tmp.split('/')[1][0:2]+htmlname_tmp
getprice_dic=getprice(pricedir,priceurl)
parseFinallyurl_rult["jdprice"]=getprice_dic['jdprice']
parseFinallyurl_rult["refprice"]=getprice_dic['refprice']
#partlists[listpageurl]):商品分類
#finalparseurl,頁面的url
#parseFinallyurl_rult["title"]):标題
#parseFinallyurl_rult["jdprice"]:京東的價格
#parseFinallyurl_rult["refprice"]:市場參考價格
#imgshowdir:商品展示的圖檔儲存位置
#imgdir:商品說明的圖檔儲存位置:jd的商品說明也是用圖檔的
#partdetail_tmp:商品的詳細資訊
#specification_tmp:商品的規則參數
#typeOrsize_tmp:商品的類型和尺寸
return str(partlists[listpageurl]).strip()+"\t"+finalparseurl.strip()+"\t"+str(parseFinallyurl_rult["title"]).strip()+"\t"+str(parseFinallyurl_rult["jdprice"]).strip()\
+"\t"+str(parseFinallyurl_rult["refprice"]).strip()+"\t"+imgshowdir.strip()+"\t"+imgdir.strip()+"\t"+partdetail_tmp.strip()+"\t"+specification_tmp.strip()+"\t"+\
typeOrsize_tmp.strip()
#判斷最後的頁面(商品詳情頁)是否被爬取了
def judgeurl(url):#優化後,使用二分法查找url(查找快了,同時也不用反複讀取檔案了)。第一次加載judgeurl_all_lines之後,維護好此list,同時新增的url也儲存到judgeurl.txt中
url=url+"\n"
global judgeurl_all_lines
find_url_flag=False
url_point=bisect.bisect(judgeurl_all_lines,url)#這裡使用二分法快速查找(前提:list是排序好的)
find_url_flag = judgeurl_all_lines and judgeurl_all_lines[url_point-1] == url
return find_url_flag
#判斷list頁面是否已經爬取完畢了
#這裡的邏輯是:第一個list中的所有url、最後list的所有url都爬取完畢了,那麼久說明list的所有page爬取完畢了(實際上是一種弱校驗)。
#調用了judgeurl得方法
def judgelist(listpageurl,finallylistpageurl):#判斷第一個、最後一個的list頁面的所有的html是否下載下傳完畢,以此判斷該類型是否處理完畢
judgelist_flag=True
parseListpageurl_rult_finally=parseListpageurl(finallylistpageurl)
finalparseurls_deep_finally=list(parseListpageurl_rult_finally['finalparseurls'])#擷取到最後的需要解析的url的清單
parseListpageurl_rult_first=parseListpageurl(listpageurl)
finalparseurls_deep_first=list(parseListpageurl_rult_first['finalparseurls'])#擷取到最後的需要解析的url的清單
for finalparseurl in finalparseurls_deep_finally:
#print finalparseurl
if judgeurl(finalparseurl):
pass
else:
judgelist_flag=False
break
if judgelist_flag==True:
for finalparseurl_first in finalparseurls_deep_first:
#print finalparseurl
if judgeurl(finalparseurl_first):
pass
else:
judgelist_flag=False
break
return judgelist_flag
#整體控制的run方法
def run():
partlists={'http://list.jd.com/list.html?cat=737,794,870':'空調'}
partlistskeys=partlists.keys()
for listpageurl in partlistskeys:
parseListpageurl_rult=parseListpageurl(listpageurl)#開始解析list頁面,如:http://list.jd.com/list.html?cat=737,794,870
totalPageNo=parseListpageurl_rult['totalPageNo']#擷取該list總共有多少頁
#print 'debug:totalPageNo',totalPageNo
finallylistpageurl=listpageurl+'&page='+str(int(totalPageNo)+1)+'&JL=6_0_0'#拼接出最後一個list頁面(list頁面有1、2、3。。。n頁)
#print 'debug:finallylistpageurl ',finallylistpageurl
if judgelist(listpageurl,finallylistpageurl):#如果該list已經爬取完畢了。那麼,就跳過這個list
print datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")+',All html done for '+str(listpageurl)+":"+str(partlists[listpageurl])+"【Done Done】,【^_^】"
continue
else:#否則就逐個沿着list,從其第1頁,開始往下爬取
for i in range(1,int(totalPageNo)+2):
finalparseurl=''
listpageurl_next=listpageurl+'&page='+str(i)+'&JL=6_0_0'
#print "debug:listpageurl_next",listpageurl_next
parseListpageurl_rult=parseListpageurl(listpageurl_next)
totalPageNo=parseListpageurl_rult['totalPageNo']#需要更行總的頁面數量,以免資料陳舊
finalparseurls_deep=list(parseListpageurl_rult['finalparseurls'])
for finalparseurl in finalparseurls_deep:
if judgeurl(finalparseurl):#判斷該具體的url是否已經爬取
print 'finalparseurl pass yet:'+finalparseurl
pass
else:
finalurl_content=getfinalurl_content(partlists,listpageurl,finalparseurl)
finalparseurl_tmp=finalparseurl+"\n"
with open("data.txt","a") as datafile:#将爬取完畢好的url寫入data.txt
datafile.writelines(finalurl_content+"\n")
with open("judgeurl.txt","a") as judgefile:#将已經爬取好的url寫入judgeurl.txt
judgefile.writelines(finalparseurl+"\n")
bisect.insort_right(judgeurl_all_lines,finalparseurl+"\n")
#主方法
if __name__ == '__main__':
reload(sys)
sys.setdefaultencoding('utf8')#設定系統預設編碼是utf8
socket.setdefaulttimeout(5)#設定全局逾時時間
global judgeurl_all_lines#設定全局變量
#不存在檔案就建立檔案,該檔案用于記錄哪些url是爬取過的,如果臨時中斷了,可以直接重新開機腳本即可
if not os.path.exists("judgeurl.txt"):
with open("judgeurl.txt",'w') as judgefile:
judgefile.close()
#每次運作隻在開始的時候讀取一次,新産生的資料(已怕去過的url)也會儲存到judgeurl.txt
with open("judgeurl.txt","r") as judgefile:
judgeurl_all_lines=judgefile.readlines()
judgeurl_all_lines.sort()#排序,因為後面需要使用到二分查找,必須先排序
#啟多個線程去爬取
Thread(target=run(),args=()).start()
Thread(target=run(),args=()).start()
#Thread(target=run(),args=()).start()
轉載于:https://blog.51cto.com/h2ofly/1585681