其實事情是這樣的,上個禮拜我去面試一家公司,工作是做爬蟲。然后有了以下對話。
面試官:你是自學的,我有一些問題問你,python的淺拷貝和深拷貝是什么?
我:呵呵
面試官:額。。。你能不能說一說你是怎么理解python的面向對象編程?
我:呵呵
面試官:額。。。。好吧,我不問你基礎了。你有沒有爬過動態(tài)的網頁?
我:有啊,我爬過豆瓣啊。
面試官:那我讓你爬視頻網站你怎么爬?F12里查看器是看不到視頻地址的!
我:看不到么?
面試官:嗯!
我:不知道。。。。。
面試官:額。。。。你這樣讓我很為難的,要不你去試試爬騰訊視頻。
我:好啊好??!
面試官:你不要想用那些模擬瀏覽器來渲染JS哦!直接抓包!
結果我回到家一看!!什么鬼!!??!


真的什么地址都沒有?。。。?br>
怎么辦?抓包?什么是抓包?。。?!
我只會用selenium加火狐瀏覽器來模擬爬動態(tài)網頁啊。。。這工作是沒希望了么?
我是個不會放棄的人??!然后就去百度了:
如何用python抓包
如何用python爬JS
后來經人指點我才明白抓包就是去F12里的network找包。。。。
然后我又百度了:
如何用python爬AJAX
仍然沒個吊用!
不過我在簡書搜索爬騰訊視頻時候學會了直接用chrome的模擬手機瀏覽器可以登錄移動端的視頻網站,可以直接看到視頻的地址鏈接。
但是。。。。。怎么用代碼爬????
好了廢話到此為止,大家也不想聽下去了。我直接進入正題吧!
經過三天的學習,我首先弄清楚了對于這種動態(tài)網站的爬取方法。
首先,用network找到一個專門接收請求的真實地址,或者后門網址。

就是這個,只要在網址里加入參數,它就會返回數據。拉下去,我們可以看道參數

這里的參數有很多并不是必須的。我先在這里提前說一下,最后我們是要根據觀察來找出規(guī)律重構出這個網址,因為我們做爬蟲的不可能上網站開F12來找信息的。
我們看下網址打開后有什么
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<root>
<exem>0</exem>
<hs>0</hs>
<ls>0</ls>
<tm>1479138997</tm>
<dltype>1</dltype>
<preview>135</preview>
<sfl>
<cnt>0</cnt>
</sfl>
<fl>
<cnt>3</cnt>
<fi>
<sl>0</sl>
<br>64</br>
<id>10703</id>
<name>sd</name>
<lmt>0</lmt>
<sb>1</sb>
<cname>標清;(270P)</cname>
<fs>4795182</fs>
</fi>
<fi>
<fs>8435750</fs>
<sl>1</sl>
<br>235</br>
<id>10712</id>
<name>hd</name>
<lmt>0</lmt>
<sb>1</sb>
<cname>高清;(480P)</cname>
</fi>
<fi>
<lmt>0</lmt>
<sb>1</sb>
<cname>超清;(720P)</cname>
<fs>17133689</fs>
<sl>0</sl>
<br>650</br>
<id>10701</id>
<name>shd</name>
</fi>
</fl>
<s>o</s>
<vl>
<vi>
<br>60</br>
<fst>5</fst>
<vh>480</vh>
<dm>0</dm>
<targetid>1619695007</targetid>
<fclip>1</fclip>
<ul>
<ui>
<vt>200</vt>
<dt>2</dt>
<dtc>10</dtc>
<url>http://222.84.158.26/vhot2.qqvideo.tc.qq.com/</url>
</ui>
<ui>
<dtc>10</dtc>
<url>http://222.84.158.27/vhot2.qqvideo.tc.qq.com/</url>
<vt>200</vt>
<dt>2</dt>
</ui>
<ui>
<url>http://222.84.158.28/vhot2.qqvideo.tc.qq.com/</url>
<vt>200</vt>
<dt>2</dt>
<dtc>10</dtc>
</ui>
<ui>
<vt>0</vt>
<dt>2</dt>
<dtc>10</dtc>
<url>http://video.dispatch.tc.qq.com/96405217/</url>
</ui>
</ul>
<st>2</st>
<videotype>23</videotype>
<hevc>0</hevc>
<dsb>0</dsb>
<ch>0</ch>
<drm>0</drm>
<enc>0</enc>
<vid>q0345aui4cn</vid>
<lnk>q0345aui4cn</lnk>
<fn>q0345aui4cn.p712.mp4</fn>
<fs>8435750</fs>
<fvkey>
79487AB1BD24866699D881C26FC8E62D2131609CE05CC1F18B76EC6481957C2416C28CAE6B21FEE56DCB157706205BC52F3928F51CC08EE79AF4E3157C4940870340CFB9B9407A55FF02A8EA1B560B00A3ADC310709553ED9AC0E8E67705AE5D4097A5370B4BF1AB75B444A3A2EB7F51
</fvkey>
<level>0</level>
<td>135.722</td>
<fmd5>9cac5ea26dbf008bce792704b6d67c97</fmd5>
<ct>21600</ct>
<sp>0</sp>
<cl>
<fc>1</fc>
<ci>
<idx>1</idx>
<cs>8435748</cs>
<cd>135.722</cd>
<cmd5>40a954202d9f663ac2443372afde8d4b</cmd5>
<keyid>q0345aui4cn.10712.1</keyid>
</ci>
</cl>
<share>1</share>
<type>9</type>
<vst>2</vst>
<iflag>0</iflag>
<ti>健忘癥老人同一問題連問17次!這名耐心的醫(yī)生火了</ti>
<vw>848</vw>
<logo>1</logo>
<pl>
<cnt>2</cnt>
<pd>
<url>http://video.qpic.cn/video_caps/0/</url>
<cd>2</cd>
<c>10</c>
<h>45</h>
<w>80</w>
<r>10</r>
<fn>q1</fn>
<fmt>40001</fmt>
</pd>
<pd>
<fmt>40002</fmt>
<url>http://video.qpic.cn/video_caps/0/</url>
<cd>2</cd>
<c>5</c>
<h>90</h>
<w>160</w>
<r>5</r>
<fn>q2</fn>
</pd>
</pl>
</vi>
<cnt>1</cnt>
</vl>
</root>
先不管,我們再打開另一個叫做getkey的網址看看里面的東西
<root>
<ct>21600</ct>
<keyid>q0345aui4cn.10712.1</keyid>
<key>
50C099826174CDA1036AC3F8BB82BEC4A6E91005384153F81E3EF477C719CBF0B442C8D533F36402878D2B7C639318CD3078DEFC435C8C865813DBEB689F66D789F410D5115A745C3019F6ABAEBFF53258F4F524A9FE978D26595B6B1732F25992A33CB6F3F2C792FA22CAC171C7087C
</key>
62154.61</br>
<sp>0</sp>
<sr>0</sr>
<level>0</level>
<s>o</s>
<filename>q0345aui4cn.p712.mp4</filename>
<levelvalid>1</levelvalid>
</root>
這么多,我們怎么知道爬蟲需要哪些東西呢?
network里是可以直接找到video的,我們看一下視頻的真實地址
`
http://183.60.171.154/vhot2.qqvideo.tc.qq.com/q0345aui4cn.p712.1.mp4?sdtfrom=v1090&type=mp4&
vkey=E1B062FA0354A56228FFE25100D1B41F83FEBC012471446999AA386A8FC8A8273AE07BFF6092B4F4AABCE8D98E7F622D71AF44C88B5D3F63A6ED4BFE45457ED0D95E67CA930861F396967521A97ED4154449A61DD95F24A7945262EEB481C3BAC8FE53A2B186F1FC111CE8D32FFBB8C1
&level=0&platform=11&br=60&fmt=hd&sp=0&guid=ED20EE2DB93337F04708204D247CB34A&locid=f9aa455a-6a68-4fd9-a4dd-0dcf179bd6b3&size=8435748&ocid=2535331244
`
很長很復雜對吧!讓我們來精簡一下,看能把哪些參數刪掉。我下面就直接放出我爬蟲爬到的精簡版的地址吧
`
http://222.84.158.29/vhot2.qqvideo.tc.qq.com/q0345aui4cn.p701.1.mp4?vkey=46994EBB71F530AC11AB11EFA265508534036712DA0187B3939F9FDE9062FBA7B5C37F0C80D72626AEEB3CD87A15B19CB064817D98C4DD0D43D113804FE8F50F67DE15DD2FC48CC06FA9AE67678FD2CE9363358A1AC9BBCDB831B1AF79E7B105
`
首先我們看到 兩個地址的IP,VKEY是不一樣的。IP這個好解釋,視頻源不一樣,地址不一樣。然后Vkey它是一直在變化的,每次打開getkey這個頁面都在變。我分析下一個視頻地址精簡后需要哪些東西
Ip=http://222.84.158.29/vhot2.qqvideo.tc.qq.com/(getinfo頁面中有)
filenname=VID +P701.1.MP4(`P701其實由getinfo中的ID的1701去掉10,改為P獲得。而.1.MP4是屬于后綴.2.mp4應該也能播放,只要有這個視頻源`)
vkey=46994EBB71F530AC11AB11EFA265508534036712DA0187B3939F9FDE9062FBA7B5C37F0C80D72626AEEB3CD87A15B19CB064817D98C4DD0D43D113804FE8F50F67DE15DD2FC48CC06FA9AE67678FD2CE9363358A1AC9BBCDB831B1AF79E7B105(`這個在getkey頁面中獲得`)
好了所以我們來重新整理下思路吧!
我要在一開始的視頻頁面獲得vid(`這個我不想解釋自己開F12查看器`)
然后在getinfo頁面獲得ID,拼接filename
在getkey頁面獲得Vkey
最后拼接成我們的視頻url
這里我放出我精簡過了的getinfo和getkey網址,只要更換vid,filename就額可以打開了
`getinfo='http://vv.video.qq.com/getinfo?vids={vid}&otype=xlm&defaultfmt=fhd'`
`getkey='http://vv.video.qq.com/getkey?format={id}&otype=xml&vt=150&vid={vid}&ran=0%2E9477521511726081\\\\&charge=0&filename={filename}&platform=11'`
這里我得強調,getkey的參數是由getinfo中獲得的!
分析得差不多了,我們開始寫爬蟲把!!
from urllib.request import Request, urlopen
from urllib.error import URLError,HTTPError
from bs4 import BeautifulSoup
import re
print('https://v.qq.com/x/page/h03425k44l2.html\\n \\
https://v.qq.com/x/cover/dn7fdvf2q62wfka/m0345brcwdk.html\\n \\
http://v.qq.com/cover/2/2iqrhqekbtgwp1s.html?vid=c01350046ds')
web = input('請輸入網址:')
if re.search(r'vid=',web) :
patten =re.compile(r'vid=(.*)')
vid=patten.findall(web)
vid=vid[0]
else:
newurl = (web.split("/")[-1])
vid =newurl.replace('.html', ' ')
從視頻頁面找出vid
getinfo='http://vv.video.qq.com/getinfo?vids={vid}&otype=xlm&defaultfmt=fhd'.format(vid=vid.strip())
def getpage(url):
req = Request(url)
user_agent = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit'
req.add_header('User-Agent', user_agent)
try:
response = urlopen(url)
except HTTPError as e:
print('The server couldn\\'t fulfill the request.')
print('Error code:', e.code)
except URLError as e:
print('We failed to reach a server.')
print('Reason:', e.reason)
html = response.read().decode('utf-8')
return(html)
打開網頁的函數
a = getpage(getinfo)
soup = BeautifulSoup(a, "html.parser")
for e1 in soup.find_all('url'):
ippattent = re.compile(r"((?:(2[0-4]\\d)|(25[0-5])|([01]?\\d\\d?))\\.){3}(?:(2[0-4]\\d)|(255[0-5])|([01]?\\d\\d?))")
if re.search(ippattent,e1.get_text()):
ip=(e1.get_text())
for e2 in soup.find_all('id'):
idpattent = re.compile(r"\\d{5}")
if re.search(idpattent,e2.get_text()):
id=(e2.get_text())
filename=vid.strip()+'.p'+id[2:]+'.1.mp4'
找到ID和拼接FILENAME
getkey='http://vv.video.qq.com/getkey?format={id}&otype=xml&vt=150&vid={vid}&ran=0%2E9477521511726081\\
&charge=0&filename={filename}&platform=11'.format(id=id,vid=vid.strip(),filename=filename)
利用getinfo中的信息拼接getkey網址
b = getpage(getkey)
key=(re.findall(r'<key>(.*)<\\/key>',b))
videourl=ip+filename+'?'+'vkey='+key[0]
print('視頻播放地址 '+videourl)
完成了

然后我就把爬蟲上傳到github發(fā)給面試官了,滿心歡喜的等著上班結束討飯生活!
但素??!
面試官:嗯,不錯!居然真的做出來了!你的期望薪酬是多少?
我:嗨,這個嗎我沒經驗。你隨便給我個六七千打發(fā)我就可以了!
面試官:嗯,你沒有經驗我們是只能按應屆生標準給你薪酬的。
我:沒事沒事,薪酬不重要。最重要先讓我進這個行業(yè)積累經驗!
過了一會
面試官:其實。。。。我們老大說你基礎太差了,雖然你自學能力不錯。但是你懂數據結構與算法嗎?
我:不會。。。。
面試官:其實爬蟲我們已經開發(fā)好了,接下來要做的是日志分析和推薦系統(tǒng)開發(fā)。
我:。。。。。。
所以,我沒拿到offer,繼續(xù)要飯。。。。
我又不看騰訊視頻,爬騰訊也沒用,把源碼放上來大家學習下吧。誰愛爬自己爬,還可以免廣告。
o(╥﹏╥)o 我什么時候才能找到工作?。???
算了,明天我就學前端去,爭取年底前當個切圖仔??!