一、最近在學習網絡爬蟲的東西,說實話,沒有怎么寫過爬蟲,Java里面使用的爬蟲也沒有怎么用過。這里主要是學習Python的時候,了解到Python爬蟲的強大,和代碼的簡介,這里會簡單的從入門看是說起,主要是了解基本的開發思路,后續會講到scrapy框架的使用,這里主要是講Python的爬蟲入門。
二、urllib、urllib2,這兩個模塊都是用來處理url請求的,這里的開始就是使用urllib和urllib2的庫進行相關操作,來看一個例子:
#!/usr/bin/env python # -*- coding:utf-8 -*- import urllib import urllib2 # 需要爬取的連接 url = "http://www.baidu.com" # 模擬的瀏覽器 headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"} # 表單數據 form_data = { "start": "0", "end": "20" } # 編碼 data = urllib.urlencode(form_data) # 設定請求 request = urllib2.Request(url, data=data, headers=headers) # 訪問獲取結果 html = urllib2.urlopen(request).read() print html
說明:這里獲取結果的方式,是通過代碼去模擬瀏覽器,來達到訪問的目的。這里的form_data 只是一個模擬ajax的請求,沒有太大的用處。
注意:urllib2.Request中如果存在data數據則是POST請求,反之GET
三、上面我們獲取到了結果,接下來就是解析,lxml是常用的一中解析方式,當然還存在其他解析的方式比如re,這里不詳細介紹:
1)在說解析之前,講一下urllib2的handler:
a、handler種類:handler分很多種,比如:cookie,proxy,auth、http等。
b、為什么使用handler:cookie處理回話的保存問題;proxy處理ip代理,訪問ip被封;auth認證處理;http處理器相關方式;
c、處理器比較常見,在會話或者代理都有很好的應用
#!/usr/bin/env python # -*- coding:utf-8 -*- import urllib import urllib2 import cookielib # 通過CookieJar()類構建一個cookieJar()對象,用來保存cookie的值 cookie = cookielib.CookieJar() # 通過HTTPCookieProcessor()處理器類構建一個處理器對象,用來處理cookie # 參數就是構建的CookieJar()對象 cookie_handler = urllib2.HTTPCookieProcessor(cookie) # 代理handler # httpproxy_handler = urllib2.ProxyHandler({"http" : "ip:port"}) # 認證代理handler # authproxy_handler = urllib2.ProxyHandler({"http" : "username:password@ip:port"}) # auth # passwordMgr = urllib2.HTTPPasswordMgrWithDefaultRealm() # passwordMgr.add_password(None, ip, username, password) # httpauth_handler = urllib2.HTTPBasicAuthHandler(passwordMgr) # proxyauth_handler = urllib2.ProxyBasicAuthHandler(passwordMgr) # opener = urllib2.build_opener(httpauth_handler, proxyauth_handler) # 構建一個自定義的opener opener = urllib2.build_opener(cookie_handler) # 通過自定義opener的addheaders的參數,可以添加HTTP報頭參數 opener.addheaders = [("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36")] # renren網的登錄接口 url = "http://www.renren.com/PLogin.do" # 需要登錄的賬戶密碼 data = {"email":"郵箱", "password":"密碼"} # 通過urlencode()編碼轉換 data = urllib.urlencode(data) # 第一次是post請求,發送登錄需要的參數,獲取cookie request = urllib2.Request(url, data = data) # 發送第一次的post請求,生成登錄后的cookie(如果登錄成功的話) response = opener.open(request) #print response.read() # 第二次可以是get請求,這個請求將保存生成cookie一並發到web服務器,服務器會驗證cookie通過 response_deng = opener.open("http://www.renren.com/410043129/profile") # 獲取登錄后才能訪問的頁面信息 html = response_deng.read() print html
2)解析(lxml):
# !/usr/bin/python # -*- coding: UTF-8 -*- import urllib2 from lxml import etree if __name__ == '__main__': # url = raw_input("請輸入需要爬取圖片的鏈接地址:") url = "https://www.baidu.com" headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"} # 讀取到的頁面 html = urllib2.urlopen(url).read() # 使用lxml的etree content = etree.HTML(html) # XPATH的寫法 img_list = content.xpath("//img/@src") # 對圖片連接處理 for link in img_list: try: if link.find("https") == -1: link = "https:" + link img = urllib2.urlopen(link).read() str_list = link.split("/") file_name = str_list[len(str_list) - 1] with open(file_name, "wb") as f: f.write(img) except Exception as err: print err
xpath的語法參考:http://www.w3school.com.cn/xpath/xpath_syntax.asp
3)另外一種使用方式(BeautifulSoup):
# !/usr/bin/python # -*- coding: UTF-8 -*- import urllib2 from bs4 import BeautifulSoupif __name__ == '__main__': url = "https://tieba.baidu.com/index.html" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"} # 讀取到的頁面 html = urllib2.urlopen(url).read() bs = BeautifulSoup(html, "lxml") img_list = bs.find_all("img", attrs={"class": ""}) # 對圖片連接處理 for img in img_list: try: link = img.get("src") if link.find("https") == -1: link = "https:" + link img = urllib2.urlopen(link).read() str_list = link.split("/") file_name = str_list[len(str_list) - 1] with open(file_name, "wb") as f: f.write(img) except Exception as err: print err
四、Selenium+PhantomJS,上面的都是針對於靜態的html文件進行的爬蟲,但是現在的網站一般都是通過ajax動態的加載數據,這里就產生了一個問題,我們必須先把js加載完成,才能進行下一步的爬蟲工作。這里也就產生了對應的框架,來做這一塊的爬蟲工作。
from selenium import webdriver from bs4 import BeautifulSoup if __name__ == '__main__': # 使用谷歌的瀏覽器 driver = webdriver.Chrome() # 獲取頁面 driver.get("https://www.douyu.com/directory/all") while True: # 確認解析方式 bs = BeautifulSoup(driver.page_source, "lxml") # 找到對應的直播間名稱 title_list = bs.find_all("h3", attrs={"class": "DyListCover-intro"}) # 直播間熱度 hot_list = bs.find_all("span", attrs={"class": "DyListCover-hot"}) # 壓縮成一個循環 for title, hot in zip(title_list, hot_list): print title.text, hot.text # 執行下一頁 if driver.page_source.find("dy-Pagination-next") == -1: break driver.find_element_by_class_name("dy-Pagination-next").click() # 退出 driver.quit()
備注:我這里使用的是chrome的瀏覽器來執行的操作,目前因為PhantomJS已經被放棄了,不建議使用
chromedriver.exe的下載需要到谷歌網站上下載(需要翻牆),我這里提供一個75版本的下載
淘寶鏡像下載地址:https://npm.taobao.org/mirrors/chromedriver/
下面提供一種針對於圖片后加載的處理:
import urllib2 import time from selenium import webdriver if __name__ == '__main__': # 使用谷歌的瀏覽器driver,需要chromedriver.exe支持(放在文件同目錄下) # 項目運行時記得讓瀏覽器全屏 driver = webdriver.Chrome() # 爬取網址 driver.get("https://www.douyu.com/directory/all") while True: # 下一頁后等待加載 time.sleep(2) # 屏幕滾動(這里的值,更具具體頁面設置) for i in xrange(1, 11): js = "document.documentElement.scrollTop=%d" % (i * 1000) driver.execute_script(js) # 等待頁面加載完成 time.sleep(1) # 獲取頁面的圖片(xpath方式) img_list = driver.find_elements_by_xpath("//div[@class='LazyLoad is-visible DyImg DyListCover-pic']/img") # 對圖片連接處理 for img in img_list: try: link = img.get_attribute("src") str_list = link.split("/") file_name = str_list[len(str_list) - 2] print file_name # 讀取圖片,寫入本地 img_data = urllib2.urlopen(link).read() with open("img/" + file_name, "wb") as f: f.write(img_data) except Exception as err: print err # 查看是否存在下一頁 if driver.page_source.find("dy-Pagination-next") == -1: break # 如果存在則跳轉至下一頁 driver.find_element_by_class_name("dy-Pagination-next").click() # 退出 driver.close()
說明:這里只是針對斗魚的圖片進行的爬蟲,其他頁面需要進一步修改,好了js的處理包括頁面需要爬取的圖片基本上就是這樣了。
該代碼只是用於學習和嘗試,不得用於其他作用
五、好了這基本上,算的上入門了吧,當然你要爬取一個完整的東西,還是需要很多功夫的,我這里只是介紹基本上常用的一些庫,和我自己測試使用的一些代碼,以及目前涉及的不懂的地方,僅供學習吧,有什么錯誤的地方還請指出。我好及時改正!!