python 基礎 網路爬蟲 day06
阿新 • • 發佈:2018-12-18
目錄
day05
1.json模組
- json.loads() json格式(物件,陣列) ->Python(字典,列表)
- json.dumps() Python(字典,元組,列表) -> json(物件,陣列)
2.Ajax動態載入
- 抓包工具抓引數:WebForms -> QueryString
- params = {QueryString中的一堆查詢引數}
- URL地址寫:抓包工具Raw下的GET地址
.3.selenium + phantomjs
- sekenium:Web自動化測試工具
- phantomjs:無介面瀏覽器(在記憶體執行頁面載入)
- 使用步驟
- 匯入模組 from selenium import webdriver from selenium.webdriver.common.keys import Keys
- 建立瀏覽器物件 driver = webdriver.PhantomJS(executable_path="...")
- 獲取網頁資訊 driver.get(url)
- 查詢節點位置 ele = driver.find_element_by_id("")
- 傳送文字 ele.send_keys("")
- 點選 cli = driver.find_element_by_class_name("") cli.click()
- 關閉 driver.quit()
- 常用方法
- driver.get(url)
- driver.page_source
- driver.page_source.find('字串') 失敗:-1 成功:非-1
- driver.find_element_by_name("屬性值")
- driver.find_elements_by_xpath("xpath表示式")
- 物件名.send_keys("")
- 物件名.click()
- 物件名.text
- driver.quit()
4.selenium + chromedriver
- chromedriver Chrome的 Webdriver
- 安裝
- 下載對應版本的chromedriver安裝包 https://chromedriver.storage.googleapis.com/index.html
- 將 chromedriver.exe 放到python安裝目錄的Scripts目錄
- 如何設定無介面模式 opt = webdriver.ChromeOptions() opt.set_headless() driver = webdriver.Chrome(options=opt) driver.get(...)
- driver如何執行JavaScript driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
day06
1.多執行緒爬蟲
- 程序執行緒回顧
- 程序
- 系統中正在執行的一個應用程式
- 1個CPU核心1次只能執行1個程序,其他程序處於非執行狀態
- N個CPU核心可以同時執行N個任務
- 執行緒
- 程序中包含的執行單元,1個程序可包含多個執行緒
- 執行緒可使用所屬程序的空間(1次只能執行1個執行緒,阻塞)
- 鎖:防止多個執行緒同時使用共享空間
- GIL:全域性解釋鎖 執行通行證,僅此一個,拿到了通行證可執行,否則 等
- 應用場景
- 多程序:大量的密集的計算
- 多執行緒:I/O密集 爬蟲:網路I/O多,適合多執行緒 寫檔案:本地磁碟I/O
- 程序
- 案例:使用多執行緒爬取 百思不得其解 段子
- 爬取目標:段子內容
- xpath表示式://div[@class="j-r-list-c-desc"]/a/text()
- 知識點
- 佇列(from queue import Queue) put() get() Queue.empty():是否為空 Queue.join():如果佇列為空,執行其他程式
- 執行緒(import threading) threading.Thread(target=...)
- 程式碼實現
'''01_多執行緒爬取百思不得其姐案例.py''' import requests from lxml import etree from queue import Queue import threading import time class bsSpider: def __init__(self): self.baseurl = "http://www.budejie.com/" self.headers = {"User-Agent":"Mozilla/5.0"} # url佇列 self.urlQueue = Queue() # 響應佇列 self.resQueue = Queue() # 生成URL佇列 def getUrl(self): for pNum in range(1,51): # 拼接URL url = self.baseurl + str(pNum) self.urlQueue.put(url) # 響應佇列 def getHtml(self): while True: url = self.urlQueue.get() res = requests.get(url,headers=self.headers) res.encoding = "utf-8" html = res.text # 放到響應佇列 self.resQueue.put(html) # 清除此任務 self.urlQueue.task_done() # 解析頁面 def getContent(self): while True: # 從響應佇列中依次獲取html原始碼 html = self.resQueue.get() parseHtml = etree.HTML(html) r_list = parseHtml.xpath('//div[@class="j-r-list-c-desc"]/a/text()') for r in r_list: print(r+"\n") # 清除任務 self.resQueue.task_done() def run(self): # 存放所有的執行緒 thread_list = [] # 獲取url佇列 self.getUrl() # 建立getHtml執行緒 for i in range(5): threadRes = threading.Thread(target=self.getHtml) thread_list.append(threadRes) # 解析執行緒 for i in range(3): threadParse = threading.Thread(target=self.getContent) thread_list.append(threadParse) # 所有執行緒開始幹活 for th in thread_list: th.setDaemon(True) th.start() # 如果佇列為空,則執行其他程式 self.urlQueue.join() self.resQueue.join() print("執行結束") if __name__ == "__main__": begin = time.time() spider = bsSpider() spider.run() end = time.time() print(end-begin)
2.BeautifulSoup
- 定義 HTML或XML的解析器,依賴於1xml
- 安裝 python -m pip install beautifulsoup4 導模組: from bs4 import BeautifulSoup
- 使用流程
- 匯入模組 from bs4 import BeautifulSoup
- 建立解析物件 soup = Beautifulsoup(html,'1xml')
- 查詢節點物件 soup.find_all(class="屬性值")
- 示例程式碼
'''02_BeautifulSoup示例.py''' from bs4 import BeautifulSoup html = '<div class="test">雄霸</div>' # 建立解析物件 soup = BeautifulSoup(html,'lxml') # 查詢節點 #r_list = soup.find_all(class_="test") r_list = soup.find_all("div",attrs={"class":"test"}) for r in r_list: print(r.get_text())
'''03_BeautifulSoup示例2.py''' from bs4 import BeautifulSoup html = '''<div class="test">雄霸</div> <div class="test">幽若</div> <div class="test2"> <span>第二夢</span> </div> ''' soup = BeautifulSoup(html,'lxml') # class為test的div的文字內容 #divs = soup.find_all("div",attrs={"class":"test"}) for div in divs: print(div.string) print(div.get_text()) # class為test2的div下的span中文字內容 divs = soup.find_all("div",attrs={"class":"test2"}) for div in divs: print(div.span.string)
- BeautifulSoup支援的解析庫
- lxml:BeautifulSoup(html,'1xml') 速度快,文件容錯力強
- python標準庫:BeautifulSoup(html,'html.parser') 速度一般
- xml解析器:BeautifulSoup(html,'xml') 速度快,文件容錯力強
- 節點選擇器
- 選擇節點 soup.節點名:soup.a 、soup.ul
- 獲取文字內容 soup.節點名.string
- 常用方法
- find_all():返回列表
- r_list = soup.find_all(屬性名="屬性值") r_list = soup.find_all(class_="test")
- r_list = soup.find_all('節點名',attrs={'名':'值'}) r_list = soup.find_all('div',attrs={"class":"test"})
- 示例:
'''04_糗事百科BeautifulSoup.py''' import requests from bs4 import BeautifulSoup url = "https://www.qiushibaike.com/" headers = {"User-Agent":"Mozilla/5.0"} res = requests.get(url,headers=headers) res.encoding = "utf-8" html = res.text # 建立解析物件 soup = BeautifulSoup(html,'lxml') r_list = soup.find_all("div",attrs={"class":"content"}) for r in r_list: s = r.span.get_text().strip() print(s) print("*" * 30)
- find_all():返回列表
3.Scrapy框架
- 安裝
- 安裝(Ubuntu)
- 安裝依賴庫 sudo apt-get install python3-dev build-essential libssl-dev libffi-dev libxml2 libxml2-dev libxslt1-dev zlib1g-dev
- 升級pyasn1模組 sudo pip3 install pyasn1==0.4.4
- 安裝Scrapy sudo pip3 install Scrapy
- 安裝(Ubuntu)
4.Scrapy框架
- Scrapy框架 非同步處理框架,可配置和可擴充套件程度非常高,Python中使用最廣泛的爬蟲框架
- 框架組成
- 引擎(Engine):整個框架核心
- 排程器(Scheduler):接受從引擎發過來的URL,入佇列
- 下載器(Downloads):下載網頁原始碼,最終返回給爬蟲程式
- 專案管道(Item Pipeline):資料處理
- 下載器中介軟體(Downloader Middlewares): 處理引擎與下載器之間的請求與響應
- 蜘蛛中介軟體(Spider Middlerwares): 處理爬蟲程式輸入響應和輸出結果以及新的請求
- Item:定義爬取結果的資料結構,爬取的資料會被賦值為Item物件
- Scrapy框架的爬取流程
- 製作Scrapy爬蟲專案步驟
- 新建專案 scrapy startproject 專案名
- 明確目標(items.py)
- 製作爬蟲程式 xxx/spiders:scrapy genspider 檔名 域名
- 處理資料(pipelines.py)
- 配置settings.py
- 執行爬蟲專案 scrapy crawl 爬蟲名
- scrapy專案檔案詳解
- 目錄結構
testspider/ ├── scrapy.cfg #專案基本配置檔案,不用改 └── testspider ├── __init__.py ├── items.py # 定義爬取資料的結構 ├── middlewares.py # 下載器中介軟體和蜘蛛中介軟體實現 ├── pipelines.py # 處理資料 ├── settings.py # 專案全域性配置 └── spiders # 存放爬蟲程式 ├── __init__.py ├── myspider.py
- settings.py配置
# 是否遵守robots協議,該為False ROBOTSTXT_OBEY = False # 最大併發量,預設為16個 CONCURRENT_REQUESTS = 32 # 下載延遲時間為3秒 DOWNLOAD_DELAY = 3 # 請求報頭 DEFAULT_REQUEST_HEADERS = { 'User-Agent': "Mozilla/5.0", 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en', } # 蜘蛛中介軟體 SPIDER_MIDDLEWARES = { 'testspider.middlewares.TestspiderSpiderMiddleware': 543, } # 下載器中介軟體 DOWNLOADER_MIDDLEWARES = { 'testspider.middlewares.TestspiderDownloaderMiddleware': 543, } # 管道檔案 ITEM_PIPELINES = { 'testspider.pipelines.TestspiderPipeline': 300, }
- 示例:抓取百度首頁原始碼,存到baidu.html中
- scrapy startproject baidu
- cd baidu/baidu
- subl items.py(此示例可不用操作)
- cd spiders
- scrapy genspider baiduspider baidu.com #爬蟲名 #域名 #start_urls def parse(self,response): with open('baidu.html','w') as f: f.write(response.text)
- subl settings.py
- 關閉robots協議
- 新增Headers
- cd spiders
- scrapy crawl baiduspider
- 目錄結構
5.pycharm執行scrapy專案
- 建立檔案begin.py 和scrapy.cfg同目錄 from scrapy import cmdline cmdline.execute("scrapy crawl baiduspider".split())
- 在 Run -> Editconfigurations -> + -> python name : spider Script : begin.py的路徑 working directory : 你自己的專案路徑
- 開啟begin.py 右上角 - 點執行