相信有了前面三章的基礎了解,我們對爬蟲的基礎知識已經有所掌握。
 
京東圖片爬蟲實戰:  
實現目標 :將京東商城手機類的商品圖片全部下載到本地。
 
首先打開京東首頁。選擇我們要下載的商品分類鏈接。
 
頁面解析: 
 
這里有很多分頁。那么如何獲取其他頁面的信息呢。
 
信息提取: 
 
信息過濾: 
 
'<img width="200" heght="200" data-img="1" data-lazy-img  = "//(.+?\.jpg)">'
 
編寫代碼: 
 
import re           #導入re模塊
import urllib.request,urllib.error   #導入urllib
def craw(url,page):     #定義一個函數html=urllib.request.urlopen(url).read() #獲取頁面信息html=str(html)        #將信息轉化為字符串pat1='<div id="plist".+? <div class="page clearfix">'result1=re.compile(pat1).findall(html) #在html1內查詢符合pat1的result1=result1[0]  #獲取起始位置的plist,也就是第一個包含了所以圖片的。pat2 ='<img width="220" height="220" data-img="1" data-lazy-img="//(.+?\.jpg)">'imagelist = re.compile(pat2).findall(result1)  #在result1內查詢所以的圖片鏈接x = 1for imageurl in imagelist:   #這里我沒有用with open、是我手動創建的文件夾。imagename = "D:/work/日常任務2/img1/"+str(page)+str(x)+".jpg"imageurl = "http://"+imageurltry:urllib.request.urlretrieve(imageurl,filename=imagename)except urllib.error.URLError as e:if hasattr(e,"code"):x+=1if hasattr(e,"reason"):x+=1x+=1
if __name__ == '__main__':for i in range(1,30): 			   #30代表獲取的范圍url= "http://list.jd.com/list.html?cat=9987,653,655&page="+str(i)craw(url,i)
 
 
鏈接爬蟲實戰:  
所謂的 鏈接爬蟲  就是說 我們想把一個網頁中所有得鏈接地址提取出來,那么我們就需要來用鏈接爬蟲來實現。
 
下面我們模擬一下獲取blog.csdb.net網頁上的所有鏈接。 
 
import re
import urllib.request
def getlink(url):headers = ("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) ""AppleWebKit/537.36 (KHTML, like Gecko)"" Chrome/39.0.2171.71 Safari/537.36")opener = urllib.request.build_opener()      #模擬成瀏覽器opener.addheaders = [headers]urllib.request.install_opener(opener)  #將opener設置為全局globalfile = urllib.request.urlopen(url)      #獲取頁面信息data = str(file.read())                 #轉換格式pat = '(https?://[^\s)";]+\.(\w|/)*)'    #根據需求構建好鏈接表達式link = re.compile(pat).findall(data)         #匹配我們需要的信息link = list(set(link))    #通過轉換去除重復元素return link
url = "http://blog.csdn.net/"  #將爬取的地址賦值給url
linklist = getlink(url)           #獲取對方網頁中包含的鏈接地址for link in linklist:       #遍歷我們需要的鏈接print(link[0])
 
可看到打印結果:
 
 
嗅事百科爬蟲實戰:  
項目目標:爬取嗅事百科上的段子。
 
本項目實現思路:
 
長話短說、看了這么久直接上代碼吧。
 
import urllib.request
import re
def getcontent(url,page):#老套路 先把自己模擬成瀏覽器   可百度搜索UA池headers = ("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64)"" AppleWebKit/537.36 (KHTML, like Gecko)"" Chrome/38.0.2125.122 UBrowser/4.0.3214.0 Safari/537.36")opener = urllib.request.build_opener()  #構造opener.addheaders = [headers]urllib.request.install_opener(opener)  #設置opener為全局data = urllib.request.urlopen(url).read().decode('utf-8')#構建對應用戶提取的正則表達式userpat ='<div class="author clearfix">.*?<h2>(.*?)</h2>'#構建內容提取的正則表達式contentpat = '<div.*?span>(.*?)</span>'#尋找所有的用戶userlist = re.compile(userpat,re.S).findall(data)   #re.S在匹配時為點任意匹配模式#所有內容contentlist = re.compile(contentpat,re.S).findall(data)# print(data)x=1for content in contentlist:content = content.replace("\n","")name = "content"+str(x)exec(name+'=content')x+=1y=1for user in userlist:name = "content"+str(y)print("用戶"+str(page)+str(y)+"是:"+user)print("內容是:")exec("print("+name+")")print("\n")y+=1
for i in range(1,3):            #rang(1,3)為爬取頁面范圍url = "http://www.qiushibaike.com/hot/page/"+str(i)getcontent(url,i)
 
運行結果如下:
 
多線程爬蟲:  
首先,什么是多線程爬蟲。
 
而多線程爬蟲,指的是爬蟲中的某部分程序可以并行執行,既在多條線上執行,這種執行結構稱為多線程爬蟲,對應的爬蟲稱為多線程爬蟲。如下圖
 
多線程爬蟲實戰:  
要在python中使用多線程,我們可以導入threading模塊使用多線程功能。我們可以定義一個類并繼承threading.Thread類,將該類定義成一個線程。
 
寫一個簡單的多線程功能:
 
import threading
class A(threading.Thread):def __init__(self):threading.Thread.__init__(self)def run(self):for i in range(10):print("我是線程A")
class B(threading.Thread):def __init__(self):threading.Thread.__init__(self)def run(self):for i in range(10):print("我是線程B")
t1=A()
t1.start()
t2=B()
t2.start()
 
 
下面是多線程爬取糗事百科段子的代碼:
 
# 使用了線程庫
import threading
# 隊列
from queue import Queue
# 解析庫
from lxml import etree
# 請求處理
import requests
# json處理
import json
import timeclass ThreadCrawl(threading.Thread):def __init__(self, threadName, pageQueue, dataQueue):#threading.Thread.__init__(self)# 調用父類初始化方法super(ThreadCrawl, self).__init__()# 線程名self.threadName = threadName# 頁碼隊列self.pageQueue = pageQueue# 數據隊列self.dataQueue = dataQueue# 請求報頭self.headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'}def run(self):print("啟動 " + self.threadName)while not CRAWL_EXIT:try:# 取出一個數字,先進先出# 可選參數block,默認值為True#1. 如果對列為空,block為True的話,不會結束,會進入阻塞狀態,直到隊列有新的數據#2. 如果隊列為空,block為False的話,就彈出一個Queue.empty()異常,page = self.pageQueue.get(False)url = "http://www.qiushibaike.com/8hr/page/" + str(page) +"/"#print urlcontent = requests.get(url, headers = self.headers).texttime.sleep(1)self.dataQueue.put(content)#print len(content)except:passprint("結束 " + self.threadName)class ThreadParse(threading.Thread):def __init__(self, threadName, dataQueue, filename, lock):super(ThreadParse, self).__init__()# 線程名self.threadName = threadName# 數據隊列self.dataQueue = dataQueue# 保存解析后數據的文件名self.filename = filename# 鎖self.lock = lockdef run(self):print("啟動" + self.threadName)while not PARSE_EXIT:try:html = self.dataQueue.get(False)self.parse(html)except:passprint("退出" + self.threadName)def parse(self, html):# 解析為HTML DOMhtml = etree.HTML(html)node_list = html.xpath('//div[contains(@id, "qiushi_tag")]')for node in node_list:# xpath返回的列表,這個列表就這一個參數,用索引方式取出來,用戶名username = node.xpath('./div/a/@title')[0]# 圖片連接image = node.xpath('.//div[@class="thumb"]//@src')#[0]# 取出標簽下的內容,段子內容content = node.xpath('.//div[@class="content"]/span')[0].text# 取出標簽里包含的內容,點贊zan = node.xpath('.//i')[0].text# 評論comments = node.xpath('.//i')[1].textitems = {"username" : username,"image" : image,"content" : content,"zan" : zan,"comments" : comments}# with 后面有兩個必須執行的操作:__enter__ 和 _exit__# 不管里面的操作結果如何,都會執行打開、關閉# 打開鎖、處理內容、釋放鎖with self.lock:# 寫入存儲的解析后的數據self.filename.write(json.dumps(items, ensure_ascii = False).encode("utf-8") + "\n")CRAWL_EXIT = False
PARSE_EXIT = Falsedef main():# 頁碼的隊列,表示20個頁面pageQueue = Queue(20)# 放入1~10的數字,先進先出for i in range(1, 21):pageQueue.put(i)# 采集結果(每頁的HTML源碼)的數據隊列,參數為空表示不限制dataQueue = Queue()filename = open("duanzi.json", "a")# 創建鎖lock = threading.Lock()# 三個采集線程的名字crawlList = ["采集線程1號", "采集線程2號", "采集線程3號"]# 存儲三個采集線程的列表集合threadcrawl = []for threadName in crawlList:thread = ThreadCrawl(threadName, pageQueue, dataQueue)thread.start()threadcrawl.append(thread)# 三個解析線程的名字parseList = ["解析線程1號","解析線程2號","解析線程3號"]# 存儲三個解析線程threadparse = []for threadName in parseList:thread = ThreadParse(threadName, dataQueue, filename, lock)thread.start()threadparse.append(thread)# 等待pageQueue隊列為空,也就是等待之前的操作執行完畢while not pageQueue.empty():pass# 如果pageQueue為空,采集線程退出循環global CRAWL_EXITCRAWL_EXIT = Trueprint("pageQueue為空")for thread in threadcrawl:thread.join()print("1")while not dataQueue.empty():passglobal PARSE_EXITPARSE_EXIT = Truefor thread in threadparse:thread.join()print("2")with lock:# 關閉文件filename.close()print("謝謝使用!")if __name__ == "__main__":main()
 
總結:  
本篇文章是基于前面3篇基礎而做出來的實戰項目。內容由易到難。
                            總結 
                            
                                以上是生活随笔 為你收集整理的004:Python爬虫实战 由易到难(图文解析) 的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。