魯智深不花 http://www.250641.live 略懂php_JavaScript_python編程 Tue, 21 Jan 2020 08:57:14 +0000 zh-CN hourly 1 https://wordpress.org/?v=4.8.12 mitmproxy 注入js代碼解決 chrome chromium 被 window.navigator.webdriver 反爬識別 http://www.250641.live/python/mitmproxy-chrome-chromium.html http://www.250641.live/python/mitmproxy-chrome-chromium.html#respond Tue, 21 Jan 2020 08:37:22 +0000 http://www.250641.live/?p=4457 有界面模式下

其實用 Selenium Webdriver chromedriver 做爬蟲也不是無敵的,同樣會被反爬。

在運行模擬瀏覽器中輸入以下js代碼

1
window.navigator.webdriver

發現是 true

window.navigator.webdriver

window.navigator.webdriver

正常打開的瀏覽器返回是 undefined

undefined

undefined

熟悉 js 的程序員就很容易判斷是否正常打開的瀏覽器

解決方案:

在啟動Chromedriver之前,為Chrome開啟開發者模式:

1
option.add_experimental_option('excludeSwitches', ['enable-automation'])

再次在開發者工具的Console選項卡中查詢window.navigator.webdriver,可以發現這個值已經自動變成 undefined 了。

undefined

undefined

這里要注意:開啟了開發者模式后一定要測試值是否已經自動變成 undefined ,Chrome 79版本會出現開發者模式 無法返回 true的情況

———ChromeDriver 79.0.3945.36 (2019-11-18)———
Supports Chrome version 79
Resolved issue 2117: Chromedriver locks when an alert()(js) is raised while taking a screenshot [Pri-2]
Resolved issue 2435: Chrome driver reports platform and platformName as XP on Win10 machine [Pri-2]
Resolved issue 2487: “Element is not clickable” when using headless [Pri-]
Resolved issue 3005: WPT test in element_clear “test_not_editable_inputs[hidden]” does not pass [Pri-3]
Resolved issue 3073: Alerts coming from backend response cause ChromeDriver in W3C mode disconnect from browser – unable to interact with Chrome anymore – java.net.ConnectException: Failed to connect to localhost/0:0:0:0:0:0:0:1:38699 [Pri-2]
Resolved issue 3133: window.navigator.webdriver is undefined when “enable-automation” is excluded in non-headless mode (should be true) [Pri-2]
Resolved issue 3148: ChromeDriver always ignores certificate errors [Pri-2]
Resolved issue 3205: Chrome driver 78 moveToElement action sometimes moves to wrong y coordinate [Pri-1]

無界面模式下

但是在無界面模式下,這么配置是無效的,我這里用到的是 mitmproxy 進行js代碼注入

安裝 mitmproxy

https://github.com/luzhisheng/mklearn/tree/master/spider/crawler_learn

modify_response.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import mitmproxy.http

t0 = 'Object.defineProperties(navigator,{webdriver:{get:() => false}});'

class Tb(object):
    def response(slef,flow: mitmproxy.http.HTTPFlow):
        if '.js' in flow.request.url or 'um.js' in flow.request.url:
                flow.response.text = t0 + flow.response.text
                print('注入成功')


addons = [
    Tb()
]

啟動 mitmdump

1
mitmdump -p 7777 -s modify_response.py

配置代理 selenium

1
self.chromeOptions.add_argument("--proxy-server=http://127.0.0.1:7777")

運行腳本 test.py

]]>
http://www.250641.live/python/mitmproxy-chrome-chromium.html/feed 0
python Selenium 瀏覽器大小 顯示等待 模擬移動設備 禁止圖片加載 進程不銷毀 及其參數 http://www.250641.live/python/selenium-setting.html http://www.250641.live/python/selenium-setting.html#respond Tue, 14 Jan 2020 17:03:32 +0000 http://www.250641.live/?p=4453 selenium.獲取瀏覽器大小、設置瀏覽器位置、最大化瀏覽器

get_window_size()     獲取瀏覽器大小

1
2
3
4
5
# 將窗口大小實例化
size_Dict = driver.get_window_size()
# 打印瀏覽器的寬和高
print("當前瀏覽器的寬:", size_Dict['width'])
print("當前瀏覽器的高:", size_Dict['height'])

set_window_size()     設置瀏覽器大小

1
driver.set_window_size(width=500, height=500, windowHandle="current")

get_window_position()    獲取瀏覽器在屏幕上的坐標

1
2
3
4
5
6
# 將窗口位置實例化
position = driver.get_window_position()
# 打印窗口坐標
print(position)
print("瀏覽器所在位置的橫坐標:", position["x"])
print("瀏覽器所在位置的縱坐標:", position["y"])

set_window_position()    設置瀏覽器在屏幕的位置

1
2
3
# 設置窗口位置并打印位置坐標
driver.set_window_position(x=100, y=200)
print(driver.get_window_position())

maximize_window()    最大化瀏覽器

1
2
3
4
# 最大化瀏覽器并輸出瀏覽器的大小和位置坐標
driver.maximize_window()
print(driver.get_window_size())
print(driver.get_window_position())

Selenium中的“顯示等待”和“隱式等待”

顯示等待(常用)

顯示等待的代碼定義了等待條件,只有該條件觸發,才執行后續代碼。下面代碼最多等待 10 秒,超時后就拋出 TimeoutException。

1
2
3
4
5
6
7
8
9
10
11
12
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Firefox()driver.get("http://somedomain/url_that_delays_loading")
try:    
    element = WebDriverWait(driver, 10).until(          
        EC.presence_of_element_located((By.ID, "myDynamicElement")))
finally:
    # 等待后執行的代碼
    # driver.quit()

隱式等待

隱式等待是在嘗試發現某個元素的時候,如果沒能立刻發現,就等待固定長度的時間。默認設置是0秒。一旦設置了隱式等待時間,它的作用范圍就是Webdriver對象實例的整個生命周期。

1
2
3
4
5
6
from selenium import webdriver

driver = webdriver.Firefox()
driver.implicitly_wait(10) # seconds
driver.get("http://somedomain/url_that_delays_loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")

Selenium+Chrome參數配置

1
2
3
4
5
6
7
8
9
10
11
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

# 實例化一個啟動參數對象
chrome_options = Options()
# 無界面運行(無窗口)
chrome_options.add_argument('--headless')
# 啟動瀏覽器
driver = webdriver.Chrome(chrome_options=chrome_options)
# 請求百度首頁
driver.get('http://www.baidu.com')

其中的 –headless 就是一個啟動項參數

常用的啟動項參數如下所示

–user-data-dir=”[PATH]” 指定用戶文件夾User Data路徑,可以把書簽這樣的用戶數據保存在系統分區以外的分區。
–disk-cache-dir=”[PATH]“ 指定緩存Cache路徑
–disk-cache-size= 指定Cache大小,單位Byte
–first run 重置到初始狀態,第一次運行
–incognito 隱身模式啟動
–disable-javascript 禁用Javascript
–omnibox-popup-count=”num” 將地址欄彈出的提示菜單數量改為num個。我都改為15個了。
–user-agent=”xxxxxxxx” 修改HTTP請求頭部的Agent字符串,可以通過about:version頁面查看修改效果
–disable-plugins 禁止加載所有插件,可以增加速度??梢酝ㄟ^about:plugins頁面查看效果
–disable-javascript 禁用JavaScript,如果覺得速度慢在加上這個
–disable-java 禁用java
–start-maximized 啟動就最大化
–no-sandbox 取消沙盒模式
–single-process 單進程運行
–process-per-tab 每個標簽使用單獨進程
–process-per-site 每個站點使用單獨進程
–in-process-plugins 插件不啟用單獨進程
–disable-popup-blocking 禁用彈出攔截
–disable-plugins 禁用插件
–disable-images 禁用圖像
–enable-udd-profiles 啟用賬戶切換菜單
–proxy-pac-url 使用pac代理 [via 1/2]
–lang=zh-CN 設置語言為簡體中文
–disk-cache-dir 自定義緩存目錄
–disk-cache-size 自定義緩存最大值(單位byte)
–media-cache-size 自定義多媒體緩存最大值(單位byte)
–bookmark-menu 在工具 欄增加一個書簽按鈕
–enable-sync 啟用書簽同步
–single-process 單進程運行Google Chrome
–start-maximized 啟動Google Chrome就最大化
–disable-java 禁止Java

官方網站參考:https://sites.google.com/a/chromium.org/chromedriver/capabilities

Selenium+Chrome模擬移動設備

1
2
3
4
5
6
# 通過設置user-agent,用來模擬移動設備
# 比如模擬 android QQ瀏覽器
options.add_argument('user-agent="MQQBrowser/26 Mozilla/5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"')

# 模擬iPhone 6
options.add_argument('user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1"')

Selenium+Chrome禁止圖片加載的參數配置

1
2
3
4
5
6
# 禁止圖片的加載
from selenium import webdriver

chrome_options = webdriver.ChromeOptions()
prefs = {"profile.managed_default_content_settings.images": 2}
chrome_options.add_experimental_option("prefs", prefs)

解決chromedriver chrome進程不銷毀問題

selenium 的內存清理不干凈已經是老問題了,網上也有很多方法比如定時 shell 命令清理,此方法在不同的操作系統就要寫不同的執行代碼很麻煩。

經過1天不斷測試,通過 driver.close() 和 driver.quit() 清理是比較有效的。

1
2
3
4
5
6
7
def stop_driver(self, driver):
        try:
            driver.close()
            driver.quit()
        except Exception as e:
            print('結束瀏覽器進程報錯:{}'.format(e))
            pass

啟動開發者模式

1
2
# 此步驟很重要,設置為開發者模式,防止被各大網站識別出來使用了Selenium
chromeOptions.add_experimental_option('excludeSwitches', ['enable-automation'])
]]>
http://www.250641.live/python/selenium-setting.html/feed 0
Python PyInstaller 打包成exe文件 windows10 和 windows 7 上運行 http://www.250641.live/python/python-pyinstaller-exe.html http://www.250641.live/python/python-pyinstaller-exe.html#respond Mon, 13 Jan 2020 15:22:52 +0000 http://www.250641.live/?p=4452 PyInstaller 打包成exe

首先需要windows系統才能打包成exe文件。

安裝 pyinstall

1
pip install pyinstall

安裝完成后,使用如下命令可以確認版本號:

1
pyinstaller --version

執行打包 myscript.py 為程序的執行文件

1
pyinstaller -F myscript.py

Pyinstaller打包后運行,程序一閃而過,怎么解決?

在exe的目錄shift+右擊選擇“在此處打開命令窗口”,然后輸入“你的名字.exe”,報錯就會有顯示。

運行的時候提示:ModuleNotFoundError: No module named ‘distutils’的錯誤.怎么解決?

查看自己virtualenv的版本,輸入如下命令

1
virtualenv --version

virtualenv 版本導致

先卸載virtualenv

1
pip uninstall virtualenv

重新安裝版本為16.1的virtualenv

1
pip install virtualenv==16.1

重新安裝程序包

pip install -r requirements.txt

具體的virtualenv教程 http://www.250641.live/python/virtualenv.html

在使用打包命令重新打包項目

1
pyinstaller -F myscript.py

使用Pyinstaller打包含scrapy模塊腳本后出錯

scrapy并未向Pyinstaller聲明VERSION文件可像數據文件一樣被打包

1
2
3
4
5
6
7
8
9
10
# Scrapy version
import pkgutil
#/scrapy目錄中__init__.py文件中注釋以下兩行
#__version__ = pkgutil.get_data(__package__, 'VERSION').decode('ascii').strip()
#version_info = tuple(int(v) if v.isdigit() else v
#                     for v in __version__.split('.'))
 
#更換為自己所安裝的版本
__version__ = "1.4.0"
#重新打包程序即可(成功后將更改還原無影響)
]]>
http://www.250641.live/python/python-pyinstaller-exe.html/feed 0
安裝 chromedriver 以及解決 chromedriver’ executable needs to be in PATH 錯誤 http://www.250641.live/python/ubuntu-anzhuang-selenium-webdriver-chromedriver.html http://www.250641.live/python/ubuntu-anzhuang-selenium-webdriver-chromedriver.html#respond Wed, 08 Jan 2020 17:19:11 +0000 http://www.250641.live/?p=4444 ubuntu 安裝 Selenium Webdriver chromedriver
1
2
3
pip install selenium
或者
pip install selenium --user

使用Selenium 操縱 chrome 瀏覽器需要配置好chromedriver,chromedriver有很多版本和瀏覽器版本需要一一對應,否則無法使用。

chromedriver 下載地址:http://chromedriver.storage.googleapis.com/index.html

查看 chrome 瀏覽器的版本—》 右上角 —》 幫助 —》 關于 google chrome

版本說明

版本說明

下載好后,在終端切換到文件所在路徑,輸入以下幾個命令并創建軟連接:

1
2
3
sudo mv -f chromedriver /usr/local/share/chromedriver
sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver
sudo ln -s /usr/local/share/chromedriver /usr/bin/chromedriver

下面測試是否成功

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class WebDirver(object):

def __init__(self):
    self.chromeOptions = webdriver.ChromeOptions()
    self.chromeOptions.add_experimental_option('excludeSwitches', ['enable-automation'])
    self.driver = webdriver.Chrome(options=self.chromeOptions)

def start_webdriver(self, url):
    self.driver.get(url)
    print(self.driver.page_source)
    self.driver.quit()

if __name__ == '__main__':
    wd = WebDirver()
    url = "https://www.baidu.com/"
    wd.start_webdriver(url)

windows 錯誤’chromedriver’ executable needs to be in PATH如何解

1.首先需要下載Chromedriver,地址:http://npm.taobao.org/mirrors/chromedriver/,下載后得到的是一個chromedriver.exe文件

2.將chromedriver.exe拷貝至谷歌瀏覽器目錄(如 C:\Program Files(x86)\Google\Chrome\Application)

3.將chromedriver.exe拷貝至python根目錄(C:\Python27)

4.將谷歌瀏覽器環境變量添加到PATH中(C:\Program Files(x86)\Google\Chrome\Application)

]]>
http://www.250641.live/python/ubuntu-anzhuang-selenium-webdriver-chromedriver.html/feed 0
virtualenv虛擬環境安裝和配置 http://www.250641.live/python/virtualenv.html http://www.250641.live/python/virtualenv.html#comments Wed, 27 Nov 2019 15:19:47 +0000 http://www.250641.live/?p=4441 先測試pip是否安裝

1
pip -h

安裝virtualenv

1
pip install virtualenv

創建虛擬環境

1
virtualenv testenv

安裝virtualenvwrapper方便管理virtualenv虛擬環境

1
pip install virtualenvwrapper
1
pip install virtualenvwrapper-win

注:windows系統安裝virtualenvwrapper后面需要加上“-win”,linux系統不需要

利用virtualenvwrapper創建虛擬環境

1
mkvirtualenv testenv

創建的同時會現實虛擬環境目錄

列出虛擬環境

1
workon

進入虛擬環境

1
workon testenv

退出虛擬環境

1
deactivate

刪除虛擬環境

1
rmvirtualenvwrapper testenv
]]>
http://www.250641.live/python/virtualenv.html/feed 2
crontab定時任務執行scrapyd爬蟲 http://www.250641.live/python/scrapy/crontab-scrapyd.html http://www.250641.live/python/scrapy/crontab-scrapyd.html#respond Thu, 10 Oct 2019 11:56:02 +0000 http://www.250641.live/?p=4437 crontab系統自帶的調度命令,通過crontab命令,我們可以在固定的間隔時間執行指定的系統指令或 shell script腳本。時間間隔的單位可以是分鐘、小時、日、月、周及以上的任意組合。這個命令非常適合周期性的日志分析或數據備份等工作。

mac 查看 crontab 是否啟動

1
sudo launchctl list | grep cron

crontab服務的重啟關閉,開啟

mac系統下

1
2
3
sudo /usr/sbin/cron start
sudo /usr/sbin/cron restart
sudo /usr/sbin/cron stop

ubuntu:

1
2
3
$sudo /etc/init.d/cron start
$sudo /etc/init.d/cron stop
$sudo /etc/init.d/cron restart

這里用它來完成scrapyd部署爬蟲定時任務推送功能。

crontab命令

1
crontab [-u user] file crontab [-u user] [ -e | -l | -r ]

命令參數

-u user:用來設定某個用戶的crontab服務;
file:file是命令文件的名字,表示將file做為crontab的任務列表文件并導入crontab。如果在命令行中沒有指定這個文件,crontab命令將接受標準輸入(鍵盤)上鍵入的命令,并將它們載入crontab。
-e:編輯某個用戶的crontab文件內容。如果不指定用戶,則表示編輯當前用戶的crontab文件。
-l:顯示某個用戶的crontab文件內容,如果不指定用戶,則表示顯示當前用戶的crontab文件內容。
-r:從/var/spool/cron目錄中刪除某個用戶的crontab文件,如果不指定用戶,則默認刪除當前用戶的crontab文件。
-i:在刪除用戶的crontab文件時給確認提示。

使用-l參數列出crontab文件

1
crontab -l

使用-r參數刪除crontab文件

1
crontab -r

刪除文件后,定時任務不會在執行

crontab的文件格式

基本格式 :
*  *  *  *  *  command
分  時  日  月  周  命令

第1列分鐘0~59

第2列小時0~23(0表示子夜)

第3列日1~31

第4列月1~12

第5列星期0~7(0和7表示星期天)

第6列要運行的命令

追加 crontab 定時任務,每分鐘觸發,會已vim方式呈現

1
crontab -e

執行scrapyd爬蟲命令

1
* * * * * curl http://localhost:6800/schedule.json -d project=xinchen -d spider=douban_spider

再次查看定時任務列表,可以看到定時任務已經添加

1
crontab -l
1
2
3
4
bash-3.2$ crontab -l
* * * * * curl http://localhost:6800/schedule.json -d project=xinchen -d spider=douban_spider
* * * * * curl http://localhost:6800/schedule.json -d project=xinchen -d spider=douban_tv_spider
* * * * * curl http://localhost:6800/schedule.json -d project=xinchen -d spider=douban_variety_show

更多例子:

1、每分鐘執行一次
* * * * *

2、每隔一小時執行一次
00 * * * *
or
* */1 * * * (/表示頻率)

3、每小時的15和30分各執行一次
15,45 * * * * (,表示并列)

4、在每天上午 8- 11時中間每小時 15 ,45分各執行一次
15,45 8-11 * * * command (-表示范圍)

5、每個星期一的上午8點到11點的第3和第15分鐘執行
3,15 8-11 * * 1 command

6、每隔兩天的上午8點到11點的第3和第15分鐘執行
3,15 8-11 */2 * * command

導入預先編好的腳本文件

一般來說,crontab用-e調出vi來編寫,但是在實際工作中經常有這種情況是,編程好了crontab文件,需要導入到生產機器上去。

1
crontab filename

更多命令

名稱 : crontab

使用權限 : 所有使用者

使用方式 :

crontab file [-u user]-用指定的文件替代目前的crontab。

crontab-[-u user]-用標準輸入替代目前的crontab.

crontab-1[user]-列出用戶目前的crontab.

crontab-e[user]-編輯用戶目前的crontab.

crontab-d[user]-刪除用戶目前的crontab.

crontab-c dir- 指定crontab的目錄。

更多關于crontab的內容

]]>
http://www.250641.live/python/scrapy/crontab-scrapyd.html/feed 0
Scrapyd部署 http://www.250641.live/python/scrapyd-deploy.html http://www.250641.live/python/scrapyd-deploy.html#respond Tue, 24 Sep 2019 08:04:56 +0000 http://www.250641.live/?p=4431 Scrapyd 是一個server,是scrapy官方推薦的部署管理spider的服務,以及通過http json控制spider。

首先先安裝scrapyd

scrapyd的安裝必須在能運行scrapy項目的虛擬環境中

1
pip install scrapyd

運行Scrapyd

1
scrapyd

2019-09-24T15:11:05+0800 [-] Loading /home/atguigu/Envs/crawler-PlsRPGJ5/lib/python3.6/site-packages/scrapyd/txapp.py…
2019-09-24T15:11:05+0800 [-] Scrapyd web console available at http://127.0.0.1:6800/
2019-09-24T15:11:05+0800 [-] Loaded.
2019-09-24T15:11:05+0800 [twisted.scripts._twistd_unix.UnixAppLogger#info] twistd 19.7.0 (/home/atguigu/Envs/crawler-PlsRPGJ5/bin/python3.6 3.6.8) starting up.
2019-09-24T15:11:05+0800 [twisted.scripts._twistd_unix.UnixAppLogger#info] reactor class: twisted.internet.epollreactor.EPollReactor.
2019-09-24T15:11:05+0800 [-] Site starting on 6800
2019-09-24T15:11:05+0800 [twisted.web.server.Site#info] Starting factory
2019-09-24T15:11:05+0800 [Launcher] Scrapyd 1.2.1 started: max_proc=16, runner=’scrapyd.runner’

啟動了Scrapyd,發現Scrapyd是一個服務器,那我們需要一個Scrapyd-client客戶端發送爬蟲代碼到Scrapyd服務中去。

這里先修改一下Scrapyd服務地址,默認scrapyd啟動是通過scrapyd就可以直接啟動,bind綁定的ip地址是127.0.0.1端口是:6800,這里為了其他主機可以訪問,需將ip地址設置為0.0.0.0

即將

1
bind_address = 127.0.0.1

改為

1
bind_address = 0.0.0.0

scrapyd的配置文件(pipenv環境路徑)

1
/home/atguigu/Envs/crawler-PlsRPGJ5/lib/python3.6/site-packages/scrapyd

訪問地址

1
http://192.168.153.166:6800/

這樣我們就可以在其他主機通過瀏覽器訪問了

安裝scrapyd-client

有了scrapyd服務,下面就要用scrapyd-client打包scrapy成egg文件發送到scrapyd服務中。

1
pip install scrapyd-client

無需在虛擬環境中,任何環境下安裝即可,只是負責打包的任務

首先cd進入項目的根目錄,然后可以使用以下內容部署項目:測試運行

1
scrapyd-deploy

返回 Unknown target: default

部署項目

檢查配置, 列出當前可用的服務器

1
scrapyd-deploy -l

xinchen_server http://localhost:6800/

列出服務器上所有的項目, 需要確保服務器上的scrapyd命令正在執行,否則會報連接失敗.首次運行的話,可以看到只有一個default項目

1
2
$ scrapyd-deploy -L xinchen_server
default

打開http://localhost:6800/, 可以看到Available projects: default

打包你的當前項目

1
scrapyd-deploy xinchen_server -p xinchen

我們也可以把項目信息寫入到配置文件中,部署時就不用指定項目信息,編輯scrapy.cfg文件,添加項目信息

1
2
3
4
5
6
7
[settings]
default = xinchen.settings

[deploy:xinchen_server]
url = http://localhost:6800/
username = root
password =

下次部署可以直接執行

1
scrapyd-deploy

運行爬蟲

1
curl http://localhost:6800/schedule.json -d project=xinchen -d spider=douban_film_comment

停止爬蟲

1
curl http://localhost:6800/cancel.json -d project=xinchen -d job=94bd8ce041fd11e6af1a000c2969bafd
]]>
http://www.250641.live/python/scrapyd-deploy.html/feed 0
pycharm中運行nosetests測試用例 http://www.250641.live/python/nosetests-test-case-in-pycharm.html http://www.250641.live/python/nosetests-test-case-in-pycharm.html#respond Thu, 20 Dec 2018 15:51:38 +0000 http://www.250641.live/?p=4402 1、配置 pycharm 調試文件

2、添加 nosetets 文件

3、直接ok確定

4、設置默認啟動的測試工具(框架)

5、tools里面選擇Python Intergated Tools

6、選擇nosetets,ok確定退出

5、在py代碼頁面右鍵,啟動測試用例,發現現在默認通過nosetets工具調試

]]>
http://www.250641.live/python/nosetests-test-case-in-pycharm.html/feed 0
我為自家大閘蟹代言 http://www.250641.live/csqw/dazhaxie.html http://www.250641.live/csqw/dazhaxie.html#respond Mon, 08 Oct 2018 15:51:26 +0000 http://www.250641.live/?p=4394 淘寶:鏈接

]]>
http://www.250641.live/csqw/dazhaxie.html/feed 0
python腳本調用youtube-dl實現視頻下載 http://www.250641.live/python/python-youtube-dl.html http://www.250641.live/python/python-youtube-dl.html#respond Thu, 02 Aug 2018 18:29:36 +0000 http://www.250641.live/?p=4284 youtube-dl是一個命令行程序,用于從YouTube.com和更多網站下載視頻。它需要Python解釋器,版本2.6,2.7或3.2+,并且支持Unix,Windows或Mac OS X中運行。而且它提供了自定義添加視頻解釋并發布到github上,這意味著可以對其進行修改,重新分發。

ubuntu系統安裝youtube-dl

1
sudo pip install youtube-dl

更新包

1
sudo -H pip install --upgrade youtube-dl

或者

1
pip install --upgrade youtube-dl

youtube-dl在大多數網站上都可以正常工作。但是,如果您想轉換視頻/音頻,視頻音頻合成,則需要avconv或ffmpeg

1
2
3
4
5
6
7
8
# 添加軟件源
$ sudo add-apt-repository ppa:jonathonf/ffmpeg-3

# 更新并安裝
$ sudo apt update && sudo apt install ffmpeg libav-tools x264 x265

# 卸載官方源的2.8版本
$ sudo apt autoremove

先來一段簡單的python腳本代碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from os import rename
import youtube_dl

def download(youtube_url):
    # 定義某些下載參數
    ydl_opts = {
        # outtmpl 格式化下載后的文件名,避免默認文件名太長無法保存
        'outtmpl': '%(id)s%(ext)s'
    }

    with youtube_dl.YoutubeDL(ydl_opts) as ydl:
        ydl.download([youtube_url])

if __name__ == '__main__':
    download('https://www.youtube.com/watch?v=VUOAszEiR8I')

代碼執行youtube網站視頻頁鏈接,交給dowload下載,字典 ydl_opts 自定義了一些下載參數。

重命名視頻文件

當你運行代碼后,發現下載的視頻文件命名不是你想要的樣子,這里了 youtube-dl 提供了一個鉤子函數進行自定義功能,代碼是這樣的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class GetItem(object):

    def rename_hook(self,d):
        # 重命名下載的視頻名稱的鉤子
        if d['status'] == 'finished':
            file_name = 'video/{}.mp4'.format(int(time.time()))
            rename(d['filename'], file_name)
            print('下載完成{}'.format(file_name))

    def download(self,youtube_url):
        # 定義某些下載參數
        ydl_opts = {
            'progress_hooks': [self.rename_hook],
            # 格式化下載后的文件名,避免默認文件名太長無法保存
            'outtmpl': '%(id)s%(ext)s',
        }
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            # 下載給定的URL列表
            result = ydl.download([youtube_url])

if __name__ == '__main__':
    getItem =  GetItem()
    getItem.download('https://www.youtube.com/watch?v=VUOAszEiR8I')

代碼 d[‘status’] == ‘finished’執行,說明了當視頻下載完成后,執行重命名文件名

自定義下載格式

在定義下載下載參數時可以寫入format:”格式” 來控制下載的格式,youtube-dl給到了以下這些默認的格式

best:選擇具有視頻和音頻的單個文件所代表的最佳質量格式。

worst:選擇具有視頻和音頻的單個文件所代表的最差質量格式。

bestvideo:選擇最佳質量的僅視頻格式(例如DASH視頻)??赡軣o法使用。

worstvideo:選擇質量最差的純視頻格式??赡軣o法使用。

bestaudio:選擇質量最佳的音頻格式??赡軣o法使用。

worstaudio:選擇質量最差的音頻格式??赡軣o法使用。

我們也可以通過視頻原有的格式來下載

在終端輸入 : youtube-dl -F 視頻地址

shell 命令查看參數

shell 命令查看參數

可以看到有h5 ,1,h3 三種格式,所以代碼可以這樣寫:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class GetItem(object):

    def rename_hook(self,d):
        # 重命名下載的視頻名稱的鉤子
        if d['status'] == 'finished':
            file_name = 'video/{}.mp4'.format(int(time.time()))
            rename(d['filename'], file_name)
            print('下載完成{}'.format(file_name))

    def download(self,youtube_url):
        # 定義某些下載參數
        ydl_opts = {
            # 我指定了要下載 “1” 這個格式,也可以填寫 best/worst/worstaudio 等等
            'format' : '1'
            'progress_hooks': [self.rename_hook],
            # 格式化下載后的文件名,避免默認文件名太長無法保存
            'outtmpl': '%(id)s%(ext)s',
        }
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            # 下載給定的URL列表
            result = ydl.download([youtube_url])

if __name__ == '__main__':
    getItem =  GetItem()
    getItem.download('https://www.youtube.com/watch?v=VUOAszEiR8I')

日志打印

如果要打印youtube-dl的輸出logs,請設置一個logger對象。 同自定義格式一樣,配置參數’logger’: MyLogger(),如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class MyLogger(object):
    def debug(self, msg):
        pass

    def warning(self, msg):
        pass

    def error(self, msg):
        print(msg)

class GetItem(object):

    def rename_hook(self,d):
        # 重命名下載的視頻名稱的鉤子
        if d['status'] == 'finished':
            file_name = 'video/{}.mp4'.format(int(time.time()))
            rename(d['filename'], file_name)
            print('下載完成{}'.format(file_name))

    def download(self,youtube_url):
        # 定義某些下載參數
        ydl_opts = {
            # 我指定了要下載 “1” 這個格式,也可以填寫 best/worst/worstaudio 等等
            'format' : '1'
            'progress_hooks': [self.rename_hook],
            # 格式化下載后的文件名,避免默認文件名太長無法保存
            'outtmpl': '%(id)s%(ext)s',
            # 打印日志
            'logger': MyLogger()
        }
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            # 下載給定的URL列表
            result = ydl.download([youtube_url])

if __name__ == '__main__':
    getItem =  GetItem()
    getItem.download('https://www.youtube.com/watch?v=VUOAszEiR8I')

提取視頻的json信息打印

現在有一個需求是:不需要下載視頻,我想要得到當前頁視頻網站的數據,可以用 extract_info 不用 download 去下載

1
2
3
4
5
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
   # extract_info 提取信息
   result = ydl.extract_info(youtube_url, download=False)

print(result)

合并音頻+視頻

可以先用youtube-dl -F “視頻地址”查看format信息,在選擇對應的格式代號如(’format’: ‘134+m4a’,)合成,但是合成視頻音頻是必須先安裝ffmpeg,文章開頭已經介紹過,不然會報錯如下:

WARNING: You have requested multiple formats but ffmpeg or avconv are not installed. The formats won’t be merged.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import youtube_dl

def download(url):

    ydl_opts = {
        'format': '134+m4a',
        'outtmpl': '%(id)s%(ext)s'
    }

    with youtube_dl.YoutubeDL(ydl_opts) as ydl:
        result = ydl.extract_info(url, download=True)

if __name__ == '__main__':
    download('https://www.youtube.com/watch?v=-5r9oswhnY4')
]]>
http://www.250641.live/python/python-youtube-dl.html/feed 0
中了亿元大奖