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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<code>import</code> <code>requests</code>
<code>import</code> <code>re </code><code>#啟動兩個必備子產品#</code>
<code>class</code><code>=</code><code>spider(</code><code>object</code><code>): </code><code>#先設定一個類,類名叫spider,他的父類是object#</code>
<code> </code><code>def</code> <code>getsource(</code><code>self</code><code>,url): </code><code>#這個類有個屬性叫getsource,它需要一個變量url# </code>
<code> </code><code>html</code><code>=</code><code>requests.get(url) </code><code>#用過request.get獲得所瞄準頁碼的源代碼#</code>
<code> </code><code>return</code><code>(html.text)</code>
<code> </code><code>def</code> <code>changepage(</code><code>self</code><code>,url,total_page): </code><code>#這個類有個屬性叫changepage#</code>
<code> </code><code>now_page</code><code>=</code><code>int</code><code>(re.search(pageNum</code><code>=</code><code>"(\d+)"</code><code>,url,re.S).group(</code><code>1</code><code>))</code>
<code> </code><code>#目前的頁數---這裡獲得的是一個純數字的,它是從url上獲得的,寫這個指令的目的是定位頭數字,前面加上了int等于把這個結果改編成int形式#</code>
<code> </code><code>page_group</code><code>=</code><code>[] </code>
<code> </code><code>for</code> <code>i </code><code>in</code> <code>range</code><code>(now_page,total_page</code><code>+</code><code>1</code><code>):</code>
<code> </code><code>link</code><code>=</code><code>re.sub(pageNum</code><code>=</code><code>"(\d+)"</code><code>,pageNum</code><code>=</code><code>i,url,re.S)</code>
<code> </code><code>#這個語句的目的是把url裡的數從now_page換到total_page+1,這樣的walk一遍,達到翻頁的目的,這裡link會生成好幾個url#</code>
<code> </code><code>page_group.append(link)</code>
<code> </code><code>return</code><code>(page_group)</code>
<code> </code><code>#把生成的那些url放到了page_group這個空清單裡#</code>
<code> </code><code>def</code> <code>geteveryclass(</code><code>self</code><code>,source):</code>
<code>#這個屬性叫geteveryclass,作者他是要把一節課所有的相關介紹内容都一把抓下來,然後再細細分掉#</code>
<code> </code><code>everyclass</code><code>=</code><code>re.findall()</code>
<code> </code><code>return</code><code>(everyclass)</code>
<code> </code><code>def</code> <code>getinto(</code><code>self</code><code>,everyclass):</code>
<code> </code><code>info</code><code>=</code><code>{}</code>
<code>#這裡生成了一個空的字典映射#</code>
<code> </code><code>info[</code><code>"title"</code><code>]</code><code>=</code><code>re.search()</code>
<code>#通過字典映射的提取功能,來從上面那一把抓裡提取出相關的東西,對應的生成物就是屬于了info這個清單裡的title這個key的value。注意!生成的東西是一個清單#</code>
<code> </code><code>info[</code><code>"content"</code><code>]</code><code>=</code><code>re.search()</code>
<code> </code><code>timeandlevel</code><code>=</code><code>re.search()</code>
<code>#這倆目标有相同的定位符,因為是清單,就一會使用序号單獨分開#</code>
<code> </code><code>info[</code><code>"classtime"</code><code>]</code><code>=</code><code>timeandlevel[</code><code>0</code><code>]</code>
<code> </code><code>info[</code><code>"classlevel"</code><code>]</code><code>=</code><code>timeandlevel[</code><code>1</code><code>]</code>
<code> </code><code>info[</code><code>"classnumber"</code><code>]</code><code>=</code><code>re.search()</code>
<code> </code><code>return</code><code>(info)</code>
<code> </code><code>def</code> <code>saveinto(</code><code>self</code><code>,classinto):</code>
<code> </code><code>f</code><code>=</code><code>open</code><code>(</code><code>"e:/pythonaaa/b/study & test/1919.txt"</code><code>,</code><code>"a"</code><code>)</code>
<code> </code><code>for</code> <code>each </code><code>in</code> <code>classinto:</code>
<code> </code><code>f.writelines(</code><code>"title:"</code><code>+</code><code>each</code><code>"title"</code><code>+</code><code>"\n"</code><code>)</code>
<code> </code><code>f.writelines(</code><code>"content:"</code><code>+</code><code>each</code><code>"content"</code><code>+</code><code>"\n"</code><code>)</code>
<code> </code><code>f.writelines(</code><code>"classtime:"</code><code>+</code><code>each</code><code>"classtime"</code><code>+</code><code>"\n"</code><code>)</code>
<code> </code><code>f.writelines(</code><code>"classlevel:"</code><code>+</code><code>each</code><code>"classlevel"</code><code>+</code><code>"\n"</code><code>)</code>
<code> </code><code>f.writelines(</code><code>"classnumber:"</code><code>+</code><code>each</code><code>"classlevel"</code><code>+</code><code>"\n"</code><code>)</code>
<code> </code><code>f.close()</code>
<code> </code><code>if</code> <code>__name__</code><code>=</code><code>"__main__"</code>
<code>classinto</code><code>=</code><code>[]</code>
<code>url</code><code>=</code><code>"http://www.jikexueyuan.com/course/?pageNum=1"</code>
<code> </code><code>jikespider</code><code>=</code><code>spider()</code>
<code>#這次行動的執行個體化名稱叫jikespider,他屬于spider這個類#</code>
<code> </code><code>all_links</code><code>=</code><code>jikespider.changepage(url.</code><code>20</code><code>)</code>
<code>#在翻頁的那個屬性裡,我們要翻到第20頁#</code>
<code> </code><code>for</code> <code>link </code><code>in</code> <code>all_links: </code><code>#把這20個頁單獨拆開#</code>
<code> </code><code>print</code><code>(</code><code>"正在處理畫面"</code><code>+</code><code>link)</code>
<code> </code><code>html</code><code>=</code><code>jikespider.getsource(link)</code>
<code>#獲得了每一個頁的源代碼#</code>
<code> </code><code>everyclass</code><code>=</code><code>jikespider.geteveryclass(html)</code>
<code>#獲得了這20頁的每一個課程的所有介紹#</code>
<code> </code><code>for</code> <code>each </code><code>in</code> <code>everyclass: </code><code>#又把這20頁裡每一個課程單獨拆開#</code>
<code> </code><code>info</code><code>=</code><code>jikespider.getinfo(each) </code>
<code>#對應的每一節課的名稱、介紹、等級、時長、人數都做成了一個字典,一一對應,生成了這樣的一個info字典映射#</code>
<code> </code><code>classinto.append(info)</code>
<code>#classinto這個空清單已經被info的内容裝滿#</code>
<code> </code><code>jikespider.saveinfo(classinfo)</code>
<code>#行動以classinfo為變量啟動了saveinfo這個屬性#</code>
==================================分割線===========================================
1)很多網站雖然顯示出來很光鮮靓麗,但是源代碼很是混亂,黏黏糊糊成一團,看起來非常惡心,但是這樣不空格不回車的代碼,在“夾逼正則”的時候非常好夾,因為沒有那些看不見的/n和/t,看到正則的定位符就可以下手。
2)有些網站源代碼寫得很清晰,這樣反而在“大錘敲縫”的定位上不太好把握,因為定位<html><div><hL<li>這種網頁語言标志符是沒用的,要定位就定位有特征的字元。
3)這個代碼寫得很棒,思路也很清晰,就好像控制一個機器人去桌子邊拿一杯水,他先給予機器人幾個能力,比如:能走路,知道哪裡是桌子,識别水杯,能水杯口向上的抓住水杯,傳回。先把這幾個能力寫明白、寫清楚。然後啟動這個機器人去做這個事情。這個代碼的思路值得學習,但是難點就是變量的不斷更替上,有一點跟不上,就會絆住。
本文轉自 蘇幕遮618 51CTO部落格,原文連結:http://blog.51cto.com/chenx1242/1730164