使用slenium+chromedriver實現(xiàn)無敵爬蟲

image.png

@概述
  • 通常各大網(wǎng)站的后臺都會有一定的反爬機制,既為了數(shù)據(jù)安全孤个,也為了減小服務器壓力

  • 通常反爬的手段的方向陋率,都是識別非瀏覽器客戶端,而selenium所做的事情逮刨,恰恰是驅(qū)動真正的瀏覽器去執(zhí)行請求和操作呕缭,只不過信號不是來源于鼠標,而是來源于selenium的API(selenium本是一個自動化的測試工具)

  • 自然人用戶能做的一切,selenium幾乎都驅(qū)動瀏覽器取做恢总,無論是否有界面迎罗,包括輸入、點擊片仿、滑動纹安,等等

  • 然而到底是鼠標操作的瀏覽器發(fā)起的請求還是API,對于服務端來說滋戳,是沒有任何差別的

@一些掌故
  • 早些的時候流行的組合并不是selenium+chrome瀏覽器驅(qū)動钻蔑,而是selenium+phantomjs
    phantomjs是一款沒有界面的瀏覽器,業(yè)界稱作無頭瀏覽器(headless)奸鸯,由于沒有界面和渲染咪笑,其運行速度要大大優(yōu)于有界面的瀏覽器,這恰恰是爬蟲喜歡的娄涩,因此紅極一時

  • 后來chrome和火狐推出了無頭模式窗怒,且運行速度很流暢,phantomjs已然壽終正寢蓄拣,因此我們表過不提

@開發(fā)環(huán)境的搭建(本文在windows下)
  • 安裝selenium:pip install selenium
  • 接著我們還要下載瀏覽器驅(qū)動
瀏覽器 對應驅(qū)動下載鏈接
Chrome https://sites.google.com/a/chromium.org/chromedriver/downloads
Edge https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
Firefox https://github.com/mozilla/geckodriver/releases
Safari https://webkit.org/blog/6900/webdriver-support-in-safari-10/
@配置環(huán)境
image.png
@導包
# 導入selenium的瀏覽器驅(qū)動接口
from selenium import webdriver

# 要想調(diào)用鍵盤按鍵操作需要引入keys包
from selenium.webdriver.common.keys import Keys

# 導入chrome選項
from selenium.webdriver.chrome.options import Options
@第一個程序:抓取頁面內(nèi)容扬虚,生成頁面快照
# 創(chuàng)建chrome瀏覽器驅(qū)動,無頭模式(超爽)
options = Options()
ptions.add_argument('--headless')
driver = webdriver.Chrome(chrome_options=chrome_options)

# 加載百度頁面
driver.get("http://www.baidu.com/")
# time.sleep(3)

# 獲取頁面名為wrapper的id標簽的文本內(nèi)容
data = driver.find_element_by_id("wrapper").text
print(data)

# 打印頁面標題 "百度一下球恤,你就知道"
print(driver.title)

# 生成當前頁面快照并保存
driver.save_screenshot("baidu.png")

# 關閉瀏覽器
driver.quit()
@模擬用戶輸入和點擊搜索辜昵,跟真人操作一樣!
    # get方法會一直等到頁面被完全加載咽斧,然后才會繼續(xù)程序堪置,通常測試會在這里選擇 time.sleep(2)
    driver.get("http://www.baidu.com/")

    # id="kw"是百度搜索輸入框,輸入字符串"程序猿"
    driver.find_element_by_id("kw").send_keys(u"程序猿")

    # id="su"是百度搜索按鈕张惹,click() 是模擬點擊
    driver.find_element_by_id("su").click()
    time.sleep(3)

    # 獲取新的頁面快照
    driver.save_screenshot("程序猿.png")

    # 打印網(wǎng)頁渲染后的源代碼
    print(driver.page_source)

    # 獲取當前頁面Cookie
    print(driver.get_cookies())

    # ctrl+a 全選輸入框內(nèi)容
    driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'a')

    # ctrl+x 剪切輸入框內(nèi)容
    driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'x')

    # 輸入框重新輸入內(nèi)容
    driver.find_element_by_id("kw").send_keys("美女")

    # 模擬Enter回車鍵
    driver.find_element_by_id("su").send_keys(Keys.RETURN)
    time.sleep(3)

    # 清除輸入框內(nèi)容
    driver.find_element_by_id("kw").clear()

    # 生成新的頁面快照
    driver.save_screenshot("美女.png")

    # 獲取當前url
    print(driver.current_url)

    # 關閉瀏覽器
    driver.quit()
@模擬用戶登錄
    # 加載微博登錄頁
    driver.get("http://passport.weibo.cn/signin/login?entry=mweibo&r=http%3A%2F%2Fweibo.cn%2F&backTitle=%CE%A2%B2%A9&vt=")
    time.sleep(3)

    # 找到輸入框舀锨,鍵入用戶名和密碼
    driver.find_element_by_id('loginName').send_keys("worio.hainan@163.com")
    driver.find_element_by_id('loginPassword').send_keys("Qq94313805")

    # 點擊登錄按鈕
    driver.find_element_by_id('loginAction').click()
    time.sleep(3)

    # 快照顯示已經(jīng)成功登錄
    print(driver.save_screenshot('jietu.png'))
    driver.quit()
@使用cookies登錄
    # 加載知乎主頁,查看快照知此時處于未登錄狀態(tài)
    driver.get("https://www.zhihu.com")
    time.sleep(1)
    print(driver.save_screenshot("zhihu_nocookies.png"))

    # 操作瀏覽器登錄知乎并抓包cookies
    zhihu_cookies = {
        # 'aliyungf_tc' : 'AQAAAAR4YFOeswAAnLFJcVRd4MKOTTXu',
        'l_n_c': '1',
        'q_c1': '8572377703ba49138d30d4b9beb30aed|1514626811000|1514626811000',
        'r_cap_id': 'MTc5M2Y0ODUzMjc0NDMzNmFkNTAzZDBjZTQ4N2EyMTc=|1514626811|a97b2ab0453d6f77c6cdefe903fd649ee8531807',
        'cap_id': 'YjQyZTEwOWM4ODlkNGE1MzkwZTk3NmI5ZGU0ZTY2YzM=|1514626811|d423a17b8d165c8d1b570d64bc98c185d5264b9a',
        'l_cap_id': 'MGE0NjFjM2QxMzZiNGE1ZWFjNjhhZmVkZWQwYzBkZjY=|1514626811|a1eb9f2b9910285350ba979681ca804bd47f12ca',
        'n_c': '1',
        'd_c0': 'AKChpGzG6QyPThyDpmyPhXaV-B9_IYyFspc=|1514626811',
        '_xsrf': 'ed7cbc18-03dd-47e9-9885-bbc1c634d10f',
        'capsion_ticket': '2|1:0|10:1514626813|14:capsion_ticket|44:NWY5Y2M0ZGJiZjFlNDdmMzlkYWE0YmNjNjA4MTRhMzY=|6cf7562d6b36288e86afaea5339b31f1dab2921d869ee45fa06d155ea3504fe1',
        '_zap': '3290e12b-64dc-4dae-a910-a32cc6e26590',
        'z_c0': '2|1:0|10:1514626827|4:z_c0|92:Mi4xYm4wY0FRQUFBQUFBb0tHa2JNYnBEQ1lBQUFCZ0FsVk5DNjAwV3dCb2xMbEhxc1FTcEJPenpPLWlqSS1qNm5KVEFR|d89c27ab659ba979a977e612803c2c886ab802adadcf70bcb95dc1951bdfaea5',
        '__utma': '51854390.2087017282.1514626889.1514626889.1514626889.1',
        '__utmb': '51854390.0.10.1514626889',
        '__utmc': '51854390',
        '__utmz': '51854390.1514626889.1.1.utmcsr=zhihu.com|utmccn=(referral)|utmcmd=referral|utmcct=/',
        '__utmv': "51854390.100--|2=registration_date=20150408=1'3=entry_date=20150408=1",
    }

    # 將用戶登錄產(chǎn)生的cookies全部添加到當前會話
    for k, v in zhihu_cookies.items():
        driver.add_cookie({'domain': '.zhihu.com', 'name': k, 'value': v})

    # 再次訪問知乎主頁并拍照宛逗,此時已經(jīng)是登錄狀態(tài)了
    driver.get("https://www.zhihu.com")
    time.sleep(3)
    print(driver.save_screenshot("zhihu_cookies.png"))

    # 退出瀏覽器
    driver.quit()
@模擬滾動條的滾動(這個用常規(guī)的爬蟲很難實現(xiàn))
    # 加載知乎主頁
    driver.get("https://www.zhihu.com")
    time.sleep(1)

    # 加載本地cookies實現(xiàn)登錄
    for k, v in zhihu_cookies.items():
        driver.add_cookie({'domain': '.zhihu.com', 'name': k, 'value': v})

    # 以登錄狀態(tài)再次發(fā)起訪問
    driver.get("https://www.zhihu.com")
    time.sleep(3)

    # 將頁面滾動到最后坎匿,執(zhí)行多次
    for i in range(3):
        js = "var q=document.documentElement.scrollTop=10000"
        driver.execute_script(js)
        time.sleep(3)

    # 截圖并退出,頁面?zhèn)冗厺L動條已經(jīng)下滑了許多像素
    print(driver.save_screenshot("zhihu_scroll.png"))
    driver.quit()
@一邊滾動一邊加載
  • 唯品會首頁的女裝圖片雷激,是一邊滾動一邊進行ajax異步加載的
  • 這個靠常規(guī)的抓包實現(xiàn)起來很麻煩
  • 使用selenium我們只需模擬用戶多次下拉滾動條替蔬,一段時間之后再重新拿取渲染好的頁面源碼,就可以像爬取靜態(tài)頁面那樣去爬取圖片了
  • 類似這種操作屎暇,其實質(zhì)就是開掛进栽,是幾乎無法防守的
    # 唯品會女裝圖片鏈接無法直接獲得
    # 請求唯品會頁面
    driver.get("https://category.vip.com/search-3-0-1.html?q=3|30036||&rp=30074|30063&ff=women|0|2|2&adidx=1&f=ad&adp=65001&adid=326630")
    time.sleep(3)

    # 逐漸滾動瀏覽器窗口,令ajax逐漸加載
    for i in range(1, 10):
        js = "var q=document.body.scrollTop=" + str(500 * i)  # PhantomJS
        js = "var q=document.documentElement.scrollTop=" + str(500 * i)  # 谷歌 和 火狐

        driver.execute_script(js)
        print('=====================================')
        time.sleep(3)

    # 拿到頁面源碼
    html = etree.HTML(driver.page_source)
    all_img_list = []

    # 得到所有圖片
    img_group_list = html.xpath("http://img[contains(@id,'J_pic')]")
    # img_group_list = html.xpath("http://img[starts-with(@id,'J_pic')]")
    # 正則表達式匹配
    # img_group_list = html.xpath(r'//img[re:match(@id, "J_pic*")]',namespaces={"re": "http://exslt.org/regular-expressions"})

    # 收集所有圖片鏈接到列表
    for img_group in img_group_list:
        img_of_group = img_group.xpath(".//@data-original | .//@data-img-back | .//@data-img-side")
        print(img_of_group)
        all_img_list.append('\n'.join(img_of_group) + '\n')

    # 將收集到的數(shù)據(jù)寫入文件
    with open('vip.txt', 'w', encoding='utf-8') as f:
        f.write('\n'.join(all_img_list))

    # 退出瀏覽器
    driver.quit()
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恭垦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌番挺,老刑警劉巖唠帝,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異玄柏,居然都是意外死亡襟衰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門粪摘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瀑晒,“玉大人,你說我怎么就攤上這事徘意√υ茫” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵椎咧,是天一觀的道長玖详。 經(jīng)常有香客問我,道長勤讽,這世上最難降的妖魔是什么蟋座? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮脚牍,結果婚禮上向臀,老公的妹妹穿的比我還像新娘。我一直安慰自己诸狭,他們只是感情好券膀,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著作谚,像睡著了一般三娩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上妹懒,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天雀监,我揣著相機與錄音,去河邊找鬼眨唬。 笑死会前,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的匾竿。 我是一名探鬼主播瓦宜,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼岭妖!你這毒婦竟也來了临庇?” 一聲冷哼從身側響起反璃,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎假夺,沒想到半個月后淮蜈,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡已卷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年梧田,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片侧蘸。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡裁眯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出讳癌,到底是詐尸還是另有隱情穿稳,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布析桥,位于F島的核電站司草,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏泡仗。R本人自食惡果不足惜埋虹,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望娩怎。 院中可真熱鬧搔课,春花似錦、人聲如沸截亦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽崩瓤。三九已至袍啡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間却桶,已是汗流浹背境输。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留颖系,地道東北人嗅剖。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像嘁扼,于是被迫代替她去往敵國和親信粮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353