來學爬蟲嗎实抡?會坐牢的那種欠母!

〇欢策、整個公司被抓

2019 年的某一個工作日,公司員工像往常一樣忙忙碌碌赏淌,某個程序員和產(chǎn)品經(jīng)理正在為了一個需求爭吵踩寇,小明帶著耳機正坐在辦公室敲代碼。

突然就來了一大群警察六水,要求所有人離開工位俺孙,雙手離開電腦、手機等設(shè)備掷贾。整個公司的人都懵了睛榄,不知道發(fā)生了什么事情,但也都照辦了想帅。

警察很快查封了公司的所有辦公用品场靴,問技術(shù)部相關(guān)人員要了服務(wù)器的信息,公司全體上下 200 多人無差別的全部送到看守所了解情況港准。

在去看守所的路上旨剥,大家都還心里想這是不是搞錯了,我們只是一個科技公司公司又沒有騙人浅缸,怎么就集體被抓了轨帜。

小明也一直認為自己沒有犯罪,自己只是一名技術(shù)人員而已衩椒,所有的工作也都是按照領(lǐng)導(dǎo)要求來執(zhí)行的蚌父,應(yīng)該很快就會把我們釋放了吧。

隨后毛萌,公司非核心人員都被釋放了出來梢什,主要集中在 HR、行政人員朝聋。最后確認公司 36 人被捕嗡午,其中大部分是程序員。

被捕后小明委托的律師事務(wù)所冀痕,就是和我們交流的兩位律師的事務(wù)所荔睹,據(jù)說小明入獄后就一直不認為自己有罪,也因一直拒絕認罪從而錯過了取保候?qū)彽臋C會言蛇。

目前小明還在等待最后的審判……

好了僻他,下面我們開始學 坐牢 爬蟲。

一腊尚、什么是爬蟲

其實你身邊到處都是爬蟲的產(chǎn)物吨拗,比如說搜索引擎 Google、百度,它們能為你提供這么多搜索結(jié)果劝篷,也都是因為它們或取了很多網(wǎng)頁信息哨鸭,然后展示給你。再來說一些商業(yè)爬蟲娇妓,比如爬取淘寶的同類商品的價格信息像鸡,好為自己的商品挑選合適的價格。爬蟲的用途很多很多哈恰,網(wǎng)上的信息成百上千只估,只要你懂爬蟲,你都能輕松獲取着绷。

二蛔钙、爬取網(wǎng)頁

這里使用 Python3 來做爬蟲,首先你得下載 Python3荠医,如果你還沒有安裝可以看一看《Linux 安裝 Python 3.x》夸楣。

然后還需要安裝 Requests,這是一個 Python 的常用的外部模塊子漩,我們需要手動安裝它豫喧。簡單的方法,使用 pip 安裝就好了幢泼。

$ pip3 install requests

現(xiàn)在我們已經(jīng)可以開始爬取網(wǎng)頁了紧显。例如,我們爬取百度百科

import requests

URL = 'https://baike.baidu.com/item/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB'

# 使用 requests 發(fā)起 Get 請求獲取網(wǎng)頁數(shù)據(jù)
request = requests.get(URL)
# 使用 utf-8 編碼缕棵,避免亂碼
request.encoding = 'utf-8'
# 獲取請求文本
html = request.text
print(html)

經(jīng)過這么幾行代碼孵班,我們已經(jīng)把百度百科的一個網(wǎng)頁的信息全部爬取下來了。

好招驴,我們換一個 URL 爬取試試篙程,比如說簡書:http://www.reibang.com/u/5fa5459c7b02。這時你會發(fā)現(xiàn)出問題了别厘。

403 Forbidden

出現(xiàn)了 403 Forbidden虱饿,訪問拒絕。這是因為簡書發(fā)現(xiàn)你可能是通過爬蟲來訪問頁面了触趴,所以會出現(xiàn)拒絕氮发。怎么辦呢?

我們可以使用偽裝冗懦,就是偽裝自己是瀏覽器爽冕,打開瀏覽器控制臺,查看請求披蕉,可以在請求頭中看到 user-agent 這一段:

user-agent

我們也仿照瀏覽器的請求颈畸,也就是在請求頭中加入 user-agent乌奇,完整代碼如下:

import requests

URL = 'http://www.reibang.com/u/5fa5459c7b02'

# 請求頭
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36'}
# 使用 requests 發(fā)起 Get 請求獲取網(wǎng)頁數(shù)據(jù)
request = requests.get(URL, headers=headers)
# 使用 utf-8 編碼,避免亂碼
request.encoding = 'utf-8'

# 獲取請求文本
html = request.text
print(html)

現(xiàn)在可以成功爬取了眯娱。

加入請求頭只是一種簡單的破解反爬技術(shù)礁苗,實際可能會遇到其他反爬取技術(shù),這就需要具體問題具體分析了困乒,比如請求帶 cookie 等寂屏。當然加請求頭的方法已經(jīng)可以成功爬取大部分網(wǎng)頁了贰谣。

目前很多網(wǎng)站都增加了頻率限制娜搂,一個 IP 在一定的時間內(nèi)訪問次數(shù)有限,最好不要去破解吱抚,一旦你的爬取頻率過高百宇,導(dǎo)致對方服務(wù)器癱瘓,這就是網(wǎng)絡(luò)攻擊了秘豹。

三携御、獲取需要的信息

雖然把網(wǎng)頁爬取下來了,但是有很多信息是我們不需要的既绕。例如啄刹,我只想看看網(wǎng)頁的標題,卻把整個網(wǎng)頁都爬取下來了凄贩。那怎么從整個網(wǎng)頁中獲取我們需要的內(nèi)容呢誓军?

如果對正則表達式很熟悉,完全可以使用正則表達式疲扎,過濾自己需要的內(nèi)容昵时;如果不熟悉還可以使用 BeautifulSoup 來幫我們解析網(wǎng)頁。

BeautifulSoup 是一個網(wǎng)頁解析的工具椒丧,有了這個工具壹甥,就可以省去大量正則表達式,簡化爬蟲代碼壶熏,快速獲取我們需要的內(nèi)容句柠。還可以查看 Beautiful Soup 文檔了解基本使用。

先安裝 BeautifulSoup:

$ pip3 install beautifulsoup4

接著再裝一個 HTML 解析器就好了:

$ pip3 install lxml

準備完畢棒假,可以開始了俄占。例如我需要獲取網(wǎng)頁的標題,獲取 <p> 標簽淆衷,獲取 <a> 標簽的連接等缸榄。

from bs4 import BeautifulSoup
import requests

URL = 'http://www.reibang.com/u/5fa5459c7b02'
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36'}

# 使用 requests 發(fā)起 Get 請求獲取網(wǎng)頁數(shù)據(jù)
request = requests.get(URL, headers=headers)
request.encoding = 'utf-8'
html = request.text

# 使用 BeautifulSoup 解析網(wǎng)頁
soup = BeautifulSoup(html, 'lxml')

# 獲取網(wǎng)頁 title
title = soup.title.string

# 獲取 <p> 標簽
p = soup.find_all('p')

# 獲取 <a> 標簽
a = soup.find_all('a')

# 獲取 <a> 標簽的鏈接
# 因為 <a> 真正的 link 在 <a href="link"> 里面,href 也可以看做是 <a> 的一個屬性祝拯,用字典的形式來讀取
a_href = [h['href'] for h in a]

# 獲取 class 為 'have-img' 的 <li> 標簽
img_li = soup.find_all('li', {'class': 'have-img'})
# 獲取 <li> 標簽里面的 <img> 標簽
for li in img_li:
    imgs = li.find_all('img')

到這里甚带,已經(jīng)小功告成她肯,爬蟲的基本使用已經(jīng)介紹完畢,如果想爬取更符合自定義標準的信息鹰贵,那么還得需要了解正則表達式才行晴氨。

四、正則表達式

正則表達式 (Regular Expression) 又稱 RegEx碉输,是用來匹配字符的一種工具籽前。在一大串字符中尋找你需要的內(nèi)容。它常被用在很多方面敷钾,比如網(wǎng)頁爬蟲枝哄,文稿整理,數(shù)據(jù)篩選等等阻荒。最簡單的一個例子:

<td>
    <img src="https://xxx/1.jpg">
    <img src="http://xxx/2.jpg">
    <img src="ftp://xxx/3.png">
</td>

我們只需要提取以 https 開頭的 url挠锥,這該如何處理呢?這是我們就需要用到正則表達式了侨赡。

正則表達式的大致匹配過程是:依次拿出表達式和文本中的字符比較蓖租,如果每一個字符都能匹配,則匹配成功羊壹;一旦有匹配不成功的字符則匹配失敗蓖宦。下面列出了正則表達式元字符和語法:

  • \d:任何數(shù)字,[0-9]
  • \D:不是數(shù)字油猫,[^\d]
  • \s:任何空白字符, 如 [\t \n \r <空格>]
  • \S:不是空白字符
  • \w:任何大小寫字母稠茂、數(shù)字,[a-zA-Z0-9]
  • \W:不是字母眨攘、數(shù)字主慰,[^\w]
  • .:匹配任何字符 (除了 \n)
  • ^:匹配開頭
  • $:匹配結(jié)尾
  • ?:匹配前一個字符0次或1次
  • *:匹配前一個字符0次或多次
  • +:匹配前一個字符1次或多次

下面舉例說明:

import re # 導(dǎo)入正則匹配模塊

# 匹配前一個字符1次或多次
re.search(r"Mon(day)+", "Monday") # <re.Match object; span=(0, 6), match='Monday'>
re.search(r"Mon(day)+", "Mon") # None
re.search(r"Mon(day)*", "Mon") # <re.Match object; span=(0, 3), match='Mon'>

# 匹配數(shù)字
re.compile('\d').match('abc123') # <re.Match object; span=(3, 4), match='1'>
re.compile('\d+').match('abc123') # <re.Match object; span=(3, 6), match='123'>

# 匹配字母和數(shù)字
re.compile('\w').match('abc123') # <re.Match object; span=(0, 1), match='a'>
re.compile('\w+').match('abc123') # <re.Match object; span=(0, 6), match='abc123'>

# 匹配開頭
re.compile('^abc').match('abc123') # <re.Match object; span=(0, 3), match='abc'>

# 匹配結(jié)尾
re.compile('123$').match('abc123') # <re.Match object; span=(3, 6), match='123'>

通過這些簡單的了解,我們就能知道以 https:// 開頭的正則表達式應(yīng)該怎么寫了:

re.compile('^(https://).+')

其中 ^(https://) 表示以 https:// 開頭鲫售,.匹配任意字符共螺,+表示匹配任意次數(shù),合并起來表示匹配以 https:// 開頭情竹,之后可以是任意字符出現(xiàn)任意次藐不。完整代碼如下:

from bs4 import BeautifulSoup
import requests
import re # 導(dǎo)入正則匹配模塊

# 獲取網(wǎng)頁
html = requests.get(URL).text

# 使用 BeautifulSoup 解析網(wǎng)頁
soup = BeautifulSoup(html, 'lxml')

# 獲取 <img> 標簽,并且 src 以 https:// 開頭
imgs = soup.find_all('img', {'src': re.compile('^(https://).*')})

print(imge) # <img src="https://xxx/1.jpg">
print(imge['src']) # https://xxx/1.jpg

如果需要獲取以 png 結(jié)尾的圖片呢秦效?只需要改一句話:

img = soup.find_all('img', {'src': re.compile('.+(.png)$')})

五雏蛮、圖片下載

現(xiàn)在我們來做一個小練習,就是爬取 國家地理中文網(wǎng) 中一個頁面上的所有圖片阱州,并且下載到本地挑秉。

查看網(wǎng)頁

可以看到,圖片是 <img> 標簽苔货,并且連接是以 http 開頭犀概,通過這樣簡單的分析立哑,就可以開始下載圖片了。

由于網(wǎng)頁可能會更新姻灶,代碼并不是一成不變的铛绰,重點是了解下載方法,同時也可以根據(jù)自己的需求去下載产喉。

from bs4 import BeautifulSoup
import requests
import re
import ssl
import urllib

# 解決訪問 HTTPS 時不受信任 SSL 證書問題
# ssl._create_default_https_context = ssl._create_unverified_context

URL = "http://www.nationalgeographic.com.cn/animals"

headers = {'User-Agent': 'Mozilla/5.0 3578.98 Safari/537.36'}

request = requests.get(URL, headers=headers)
request.encoding = 'utf-8'
html = request.text
soup = BeautifulSoup(html, 'lxml')

# 獲取 'http://' 或 'https://'  開頭的 <img> 標簽
img_urls = soup.find_all('img', {'src': re.compile('^(http(s)?://).+')})
for i in range(len(img_urls)):
    url = img_urls[i]['src']
    # 下載圖片
    urllib.request.urlretrieve(url, '/Users/Desktop/Picture/' + str(i) + '.jpg')

圖片已經(jīng)下載完成

下載圖片

現(xiàn)在可以爬取一個網(wǎng)頁上的圖片了捂掰,如果我想把整個 國家地理中文網(wǎng)所有的圖片都下載呢?

import time
from bs4 import BeautifulSoup
import re
import requests
import urllib
import ssl

ssl._create_default_https_context = ssl._create_unverified_context

base_url = 'http://www.ngchina.com.cn/animals/'
headers = {'User-Agent': 'Mozilla/5.0 3578.98 Safari/537.36'}

def crawl(url):
    '''
    爬取網(wǎng)頁
    :param url: url
    :return: url and current web content
    '''
    request = requests.get(url, headers=headers)
    request.encoding = 'utf-8'
    html = request.text
    return url, html


def parse(url, html):
    '''
    解析網(wǎng)頁
    '''
    soup = BeautifulSoup(html, 'lxml')
    title = soup.title.string  # 獲取網(wǎng)頁標題
    # 獲取當前頁面上的鏈接曾沈,待下個循環(huán)爬取这嚣,只拿國家地理中文網(wǎng)的鏈接
    urls = soup.find_all('a', {"href": re.compile('^(http://www.ngchina).+')})
    page_urls = set([url['href'] for url in urls])  # 鏈接去重
    download_img(soup)  # 下載圖片
    return title, url, page_urls


def download_img(soup):
    """
    下載以 http 或 https 開頭的圖片
    """
    img_urls = soup.find_all('img', {'src': re.compile('^(http(s)?://).+')})
    for i in range(len(img_urls)):
        url = img_urls[i]['src']
        urllib.request.urlretrieve(url, '/Users/terry-jri/Desktop/Picture/' + str(time.time()) + '.jpg')


# 待爬取網(wǎng)頁url
unseen = set([base_url, ])

# 已爬取網(wǎng)頁url
seen = set()

count, t1 = 1, time.time()

while len(unseen) != 0:  # still get some url to visit
    if len(seen) > 100:  # max count
        break

    print('\nCrawling...')
    htmls = [crawl(url) for url in unseen]

    print('\nParsing...')
    results = [parse(url, html) for url, html in htmls]

    print('\nAnalysing...')
    seen.update(unseen)  # seen the crawled
    unseen.clear()  # nothing unseen

    for title, url, page_urls in results:
        print(count, title, url)
        count += 1
        unseen.update(page_urls - seen)  # get new url to crawl

print('Total time: %.1f s' % (time.time() - t1,))

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市晦譬,隨后出現(xiàn)的幾起案子疤苹,更是在濱河造成了極大的恐慌互广,老刑警劉巖敛腌,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異惫皱,居然都是意外死亡像樊,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門旅敷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來生棍,“玉大人,你說我怎么就攤上這事媳谁⊥康危” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵晴音,是天一觀的道長柔纵。 經(jīng)常有香客問我,道長锤躁,這世上最難降的妖魔是什么搁料? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮系羞,結(jié)果婚禮上郭计,老公的妹妹穿的比我還像新娘。我一直安慰自己椒振,他們只是感情好昭伸,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著澎迎,像睡著了一般庐杨。 火紅的嫁衣襯著肌膚如雪宋下。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天辑莫,我揣著相機與錄音学歧,去河邊找鬼。 笑死各吨,一個胖子當著我的面吹牛枝笨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播揭蜒,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼横浑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了屉更?” 一聲冷哼從身側(cè)響起徙融,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瑰谜,沒想到半個月后欺冀,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡萨脑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年隐轩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渤早。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡职车,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鹊杖,到底是詐尸還是另有隱情悴灵,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布骂蓖,位于F島的核電站积瞒,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏涯竟。R本人自食惡果不足惜赡鲜,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望庐船。 院中可真熱鬧银酬,春花似錦、人聲如沸筐钟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽篓冲。三九已至李破,卻和暖如春宠哄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嗤攻。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工毛嫉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人妇菱。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓承粤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親闯团。 傳聞我的和親對象是個殘疾皇子辛臊,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容