天天看点

一个网络爬虫实验

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

继续阅读