之前就對Python爬蟲和機器學習很感興趣,最近終於是開始學習了....
好吧,不是沒時間,而是有時間的時候都干別的了,所以對於還需要抽時間學我只能是‘好吧’的態度...
今天急急忙忙的就上手了一個小例子,隨便爬了網站試試,算是入門級的吧,但是由於興趣所以還是非常激動的。
前兩天看了下Python基礎,因為有其他語言的基礎加上HTML、js都是會的,所以也就是看了下基礎的語法和java有啥不同,然後一些理論知識。
我是在廖雪峰博客和自己找的一些基礎視頻看的,初步了解了下Python的語法,還有Python和Java的區別,對於兩種語言實現相同功能的不同寫法等等。
然後了解了下Python的歷史,和版本的區別。
我選用的是Python3.7 安裝程序。
一些基礎的知識暫時沒做筆記,基本是參考廖雪峰博客還有網上的一些視頻網站視頻就能明白的。 要深入的話最好是買下書籍來看吧。
基礎還有些並沒有很通透吧,想著做的時候再單個知識點去深入。
好吧,言歸正傳。這個示例還是非常簡單得,因為之前有看過相關視頻,所以還算是理解。
目標是爬取美圖吧首頁的一些數據。
獲取頁面
Python對網頁訪問首先需要引入urllib.request (之前直接用urllib不行好像是版本的原因,感覺我都學岔版本了)
urllib中有 urllib.request.urlopen(str) 方法用於打開網頁並返回一個對象,調用這個對象的read()方法後能直接獲得網頁的源代碼,內容與浏覽器右鍵查看源碼的內容一樣。
print(chardet.detect(htmlCode))
輸出{'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'} ,獲取的爬取內容的編碼方式
然後輸出源代碼
import urllib.request
import chardet
page = urllib.request.urlopen('http://www.meituba.com/tag/juesemeinv.html') #打開網頁
htmlCode = page.read() #獲取網頁源代碼
print(chardet.detect(htmlCode)) #打印返回網頁的編碼方式
print(htmlCode.decode('utf-8')) #打印網頁源代碼
注意:直接輸出print(htmlCode)的話會有編碼問題,然後去原網頁查看源代碼的編碼,但是運行htmlCode.decode("UTF-8")
的時候,出現下面的錯誤:
line 19, in <module>
data = data.decode("UTF-8")
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
可能是print的原因,也有肯能不是utf-8編碼。可以試試,data = htmlCode.decode("UTF-8") print(data)
把爬取的網頁源代碼保存到文檔中
import urllib.request
import chardet
page = urllib.request.urlopen('http://www.meituba.com/tag/juesemeinv.html') #打開網頁
htmlCode = page.read() #獲取網頁源代碼
#print(chardet.detect(htmlCode)) #查看編碼方式
data = htmlCode.decode('utf-8')
#print(data) #打印網頁源代碼
pageFile = open('pageCode.txt','wb')#以寫的方式打開pageCode.txt
pageFile.write(htmlCode)#寫入
pageFile.close()#開了記得關
這樣在test.py目錄下就會生成一個pageCode.txt文件了。
獲取其他信息
打開pageCode.txt文件(也可以直接在原網頁F12調試獲取),查看需要獲取數據的標簽信息。
比如我現在要拿圖片
寫出圖片的正則表達式: reg = r'src="(.+?\.jpg)"'
解釋下吧——匹配以src="開頭然後接一個或多個任意字符(非貪婪),以.jpg" 結尾的字符串。比如圖中紅框內src後 雙引號裡的鏈接就是一個匹配的字符串。
接著我們要做的就是從get_html方法返回的辣麼長一串字符串中 拿到 滿足正則表達式的 字符串。
用到python中的re庫中的 re.findall(str) 它返回一個滿足匹配的字符串組成的列表
import urllib.request
import chardet
import re
page = urllib.request.urlopen('http://www.meituba.com/tag/juesemeinv.html') #打開網頁
htmlCode = page.read() #獲取網頁源代碼
#print(chardet.detect(htmlCode)) #查看編碼方式
data = htmlCode.decode('utf-8')
#print(data) #打印網頁源代碼
#pageFile = open('pageCode.txt','wb')#以寫的方式打開pageCode.txt
#pageFile.write(htmlCode)#寫入
#pageFile.close()#開了記得關
reg = r'src="(.+?\.jpg)"'#正則表達式
reg_img = re.compile(reg)#編譯一下,運行更快
imglist = reg_img.findall(data)#進行匹配
for img in imglist:
print(img)
輸出結果
然後將圖片下載到本地
urllib庫中有一個 urllib.request.urlretrieve(鏈接,名字) 方法,它的作用是以第二個參數為名字下載鏈接中的內容,我們來試用一下
x = 0
for img in imglist:
print(img)
urllib.request.urlretrieve('http://ppic.meituba.com/uploads/160322/8-1603220U50O23.jpg', '%s.jpg' % x)
x += 1
發現報錯
應該是被攔截了,只有通過浏覽器訪問的才可以下載,防爬蟲的。
加上請求頭應該可以的。。。
換個網站試試吧,百度圖片https://image.baidu.com/ 。。也不行啊
新浪圖片http://photo.sina.com.cn/。。終於OK了。。
再試一個: 爬取網絡小說
首先爬取所有章節,再根據每個章節的超鏈接獲取每章的正文內容保存到本地
import re
import urllib.request
def getGtmlCode():
html = urllib.request.urlopen("http://www.quanshuwang.com/book/44/44683").read() #獲取網頁源代碼
html = html.decode("gbk") #轉成該網站格式
reg = r'<li><a href="(.*?)" title=".*?">(.*?)</a></li>' #根據網站樣式匹配的正則:(.*?)可以匹配所有東西,加括號為我們需要的
reg = re.compile(reg)
urls = re.findall(reg, html)
for url in urls:
#print(url)
chapter_url = url[0] #章節路徑
chapter_title = url[1] #章節名
chapter_html = urllib.request.urlopen(chapter_url).read() #獲取該章節的全文代碼
chapter_html = chapter_html.decode("gbk")
chapter_reg = r'</script> .*?<br />(.*?)<script type="text/javascript">' #匹配文章內容
chapter_reg = re.compile(chapter_reg,re.S)
chapter_content = re.findall(chapter_reg, chapter_html)
for content in chapter_content:
content = content.replace(" ","") #使用空格代替
content = content.replace("<br />","") #使用空格代替
print(content)
f = open('{}.txt'.format(chapter_title),'w') #保存到本地
f.write(content)
getGtmlCode()
最後結果:
。。好多網站並沒那麼容易就爬的到數據啊(頁面規則不統一),之前想爬微博的數據但是需要登錄或者其他的驗證(反爬蟲機制), 還有就是把爬取的直接存到數據庫再通過一定規則展現出來等等(爬下來的數據處理)。。 後面還要再學吧,知識學不完滴。