正文
〇. python 基礎
先放上python 3 的官方文檔:https://docs.python.org/3/ (看文檔是個好習慣)
關于python 3 基礎文法方面的東西,網上有很多,大家可以自行查找.
一. 最簡單的爬取程式
爬取百度首頁源代碼:
來看上面的代碼:
- 對于python 3來說,urllib是一個非常重要的一個子產品 ,可以非常友善的模拟浏覽器通路網際網路,對于python 3 爬蟲來說, urllib更是一個必不可少的子產品,它可以幫助我們友善地處理URL.
- urllib.request是urllib的一個子子產品,可以打開和處理一些複雜的網址
The urllib.requestmodule defines functions and classes which help in opening URLs (mostly HTTP) in a complex world — basic and digest authentication, redirections, cookies and more.
- urllib.request.urlopen()方法實作了打開url,并傳回一個 http.client.HTTPResponse對象,通過http.client.HTTPResponse的read()方法,獲得response body,轉碼最後通過print()列印出來.
urllib.request.urlopen(url, data=None, [timeout, ]***, cafile=None, capath=None, cadefault=False, context=None)For HTTP and HTTPS URLs, this function returns a http.client.HTTPResponseobject slightly modified.< 出自: https://docs.python.org/3/library/urllib.request.html >
- decode('utf-8')用來将頁面轉換成utf-8的編碼格式,否則會出現亂碼
二 模拟浏覽器爬取資訊
在通路某些網站的時候,網站通常會用判斷通路是否帶有頭檔案來鑒别該通路是否為爬蟲,用來作為反爬取的一種政策。
先來看一下Chrome的頭資訊(F12打開開發者模式)如下:
如圖,通路頭資訊中顯示了浏覽器以及系統的資訊(headers所含資訊衆多,具體可自行查詢)
Python中urllib中的request子產品提供了模拟浏覽器通路的功能,代碼如下:
from urllib import request
url = 'http://www.baidu.com'
# page = request.Request(url)
# page.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36')
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
page = request.Request(url, headers=headers)
page_info = request.urlopen(page).read().decode('utf-8')
print(page_info)
可以通過add_header(key, value) 或者直接以參數的形式和URL一起請求通路,urllib.request.Request()
urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
在學習中有迷茫不知如何學習的朋友小編推薦一個學Python的學習q u n 227 -435- 450可以來了解一起進步一起學習!免費分享視訊資料
三 爬蟲利器Beautiful Soup
Beautiful Soup是一個可以從HTML或XML檔案中提取資料的Python庫.它能夠通過你喜歡的轉換器實作慣用的文檔導航,查找,修改文檔的方式.
文檔中的例子其實說的已經比較清楚了,那下面就以爬取簡書首頁文章的标題一段代碼來示範一下:
先來看簡書首頁的源代碼:
可以發現簡書首頁文章的标題都是在<a/>标簽中,并且class='title',是以,通過
find_all('a', 'title')
便可獲得所有的文章标題,具體實作代碼及結果如下:
# -*- coding:utf-8 -*-
from urllib import request
from bs4 import BeautifulSoup
url = r'http://www.jianshu.com'
# 模拟真實浏覽器進行通路
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
page = request.Request(url, headers=headers)
page_info = request.urlopen(page).read()
page_info = page_info.decode('utf-8')
# 将擷取到的内容轉換成BeautifulSoup格式,并将html.parser作為解析器
soup = BeautifulSoup(page_info, 'html.parser')
# 以格式化的形式列印html
# print(soup.prettify())
titles = soup.find_all('a', 'title') # 查找所有a标簽中class='title'的語句
# 列印查找到的每一個a标簽的string
for title in titles:
print(title.string)
Beautiful Soup支援Python标準庫中的HTML解析器,還支援一些第三方的解析器,下表列出了主要的解析器,以及它們的優缺點:
四 将爬取的資訊存儲到本地
之前我們都是将爬取的資料直接列印到了控制台上,這樣顯然不利于我們對資料的分析利用,也不利于儲存,是以現在就來看一下如何将爬取的資料存儲到本地硬碟。
1 對.txt檔案的操作
讀寫檔案是最常見的操作之一,python3 内置了讀寫檔案的函數:open
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None))Open file and return a corresponding file object. If the file cannot be opened, an OSErroris raised.
其中比較常用的參數為file和mode,參數file為檔案的路徑,參數mode為操作檔案的方式(讀/寫),函數的傳回值為一個file對象,如果檔案操作出現異常的話,則會抛出 一個OSError
還以簡書首頁文章題目為例,将爬取到的文章标題存放到一個.txt檔案中,具體代碼如下:
# -*- coding:utf-8 -*-
from urllib import request
from bs4 import BeautifulSoup
url = r'http://www.jianshu.com'
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
page = request.Request(url, headers=headers)
page_info = request.urlopen(page).read().decode('utf-8')
soup = BeautifulSoup(page_info, 'html.parser')
titles = soup.find_all('a', 'title')
try:
# 在E盤以隻寫的方式打開/建立一個名為 titles 的txt檔案
file = open(r'E: itles.txt', 'w')
for title in titles:
# 将爬去到的文章題目寫入txt中
file.write(title.string + '
')
finally:
if file:
# 關閉檔案(很重要)
file.close()
open中mode參數的含義見下表:
其中't'為預設模式,'r'相當于'rt',符号可以疊加使用,像'r+b'
另外,對檔案操作一定要注意的一點是:打開的檔案一定要關閉,否則會占用相當大的系統資源,是以對檔案的操作最好使用try:...finally:...的形式。但是try:...finally:...的形式會使代碼顯得比較雜亂,所幸python中的with語句可以幫我們自動調用close()而不需要我們寫出來,是以,上面代碼中的try:...finally:...可使用下面的with語句來代替:
with open(r'E: itle.txt', 'w') as file:
for title in titles:
file.write(title.string + '
')
效果是一樣的,建議使用with語句
2 圖檔的儲存
有時候我們的爬蟲不一定隻是爬取文本資料,也會爬取一些圖檔,下面就來看怎麼将爬取的圖檔存到本地磁盤。
我們先來選好目标,知乎話題:女生怎麼健身鍛造好身材? (單純因為圖多,不要多想哦 (# _ # ) )
看下頁面的源代碼,找到話題下圖檔連結的格式,如圖:
可以看到,圖檔在img标簽中,且class=origin_image zh-lightbox-thumb,而且連結是由.jpg結尾,我們便可以用Beautiful Soup結合正規表達式的方式來提取所有連結,如下:
links = soup.find_all('img', "origin_image zh-lightbox-thumb",src=re.compile(r'.jpg$'))
提取出所有連結後,使用request.urlretrieve來将所有連結儲存到本地
Copy a network object denoted by a URL to a local file. If the URL points to a local file, the object will not be copied unless filename is supplied. Return a tuple (filename, headers)where filename is the local file name under which the object can be found, and headers is whatever the info()method of the object returned by urlopen()returned (for a remote object). Exceptions are the same as for urlopen().
具體實作代碼如下:
# -*- coding:utf-8 -*-
import time
from urllib import request
from bs4 import BeautifulSoup
import re
url = r'https://www.zhihu.com/question/22918070'
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
page = request.Request(url, headers=headers)
page_info = request.urlopen(page).read().decode('utf-8')
soup = BeautifulSoup(page_info, 'html.parser')
# Beautiful Soup和正規表達式結合,提取出所有圖檔的連結(img标簽中,class=**,以.jpg結尾的連結)
links = soup.find_all('img', "origin_image zh-lightbox-thumb",src=re.compile(r'.jpg$'))
# 設定儲存的路徑,否則會儲存到程式目前路徑
local_path = r'E:Pic'
for link in links:
print(link.attrs['src'])
# 儲存連結并命名,time防止命名沖突
request.urlretrieve(link.attrs['src'], local_path+r'%s.jpg' % time.time())
運作結果