程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

第一個Python小爬蟲

編輯:Python

之前就對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>&nbsp;&nbsp;&nbsp;&nbsp;.*?<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("&nbsp;&nbsp;&nbsp;&nbsp;","") #使用空格代替
content = content.replace("<br />","") #使用空格代替
print(content)
f = open('{}.txt'.format(chapter_title),'w') #保存到本地
f.write(content)
getGtmlCode()

最後結果:

。。好多網站並沒那麼容易就爬的到數據啊(頁面規則不統一),之前想爬微博的數據但是需要登錄或者其他的驗證(反爬蟲機制), 還有就是把爬取的直接存到數據庫再通過一定規則展現出來等等(爬下來的數據處理)。。 後面還要再學吧,知識學不完滴。


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved