天天看點

一個網絡爬蟲實驗

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 &amp; 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)有些網站源代碼寫得很清晰,這樣反而在“大錘敲縫”的定位上不太好把握,因為定位&lt;html&gt;&lt;div&gt;&lt;hL&lt;li&gt;這種網頁語言标志符是沒用的,要定位就定位有特征的字元。

3)這個代碼寫得很棒,思路也很清晰,就好像控制一個機器人去桌子邊拿一杯水,他先給予機器人幾個能力,比如:能走路,知道哪裡是桌子,識别水杯,能水杯口向上的抓住水杯,傳回。先把這幾個能力寫明白、寫清楚。然後啟動這個機器人去做這個事情。這個代碼的思路值得學習,但是難點就是變量的不斷更替上,有一點跟不上,就會絆住。

 本文轉自 蘇幕遮618 51CTO部落格,原文連結:http://blog.51cto.com/chenx1242/1730164

繼續閱讀