【00】Python爬虫初次开发

博客迁移。欢迎访问 stevehawk.tk sttev.com

Python爬虫初次开发:

  这周四讲了正则表达式,晚上就开始摸索着写一个网络爬虫。这个爬虫的功能就是从指定的网页开始,爬取这个网页里所有的链接,然后进入这些链接继续爬取新的链接,不断继续这个过程,并保存下所有爬取到的链接。这个爬虫目前还没有什么实际用处,后续可以在此基础上开发搜索指定信息等功能。

  这个Python程序将用到以下模块:urllib, re, time

  urllib:用来调用urlopen函数打开链接

  re:编译正则表达式

  time:用于计时[可选]

以下是我的代码:

 1 #code by STeveHawk
 2 #Email stevehawk@qq.com
 3 
 4 from urllib.request import urlopen
 5 import re
 6 import time
 7 fo=open("pc00_result.txt","w")          #打开要用于储存链接的文本文档
 8 list=[]                                 #储存所有的链接
 9 x=0                                     #爬过的链接次数
10 connected=0                             #成功连上的数量
11 num=0                                   #上一次储存的最后一个链接的索引
12 list.append(input("输入网址:"))
13 xn=int(input("输入爬虫总次数:"))
14 start=time.clock()                      #开始计时
15 while x<=xn:
16     if x>=len(list):                    #次数超出总链接数量就结束
17         end=time.clock()                #结束计时
18         print("爬虫结束...!")
19         print("本次爬虫共爬过{}个网站,爬得{}个链接".format(connected, len(list)-1))
20         print("共耗时{:.3f}s".format(end-start))
21         fo.writelines("爬虫结束...!\n")
22         fo.writelines("本次爬虫共爬过{}个网站,爬得{}个链接\n".format(connected, len(list)-1))
23         fo.writelines("共耗时{:.3f}s\n".format(end-start))
24         break
25     try:
26         print("No.{}".format(x))
27         fo.writelines("No.{}\n".format(x))
28         print("正在连接{}".format(list[x]))
29         fo.writelines("正在连接{}\n".format(list[x]))
30         temp=urlopen(list[x],timeout=10)                    #打开链接 10秒超时
31         temp=temp.read().decode("utf-8")                    #读取网页内容并以utf-8方式解码
32         print("已连接上{}".format(list[x]))
33         fo.writelines("已连接上{}\n".format(list[x]))
34         patten=re.compile(r'https?://[^\\\'"\.].+?[^\\\'"](?:/|com|org|net|cn|cc|tv)')
35         print("正在解析{}".format(list[x]))
36         fo.writelines("正在解析{}\n".format(list[x]))
37         temp0=re.findall(patten, temp)                      #在之前读取的内容里进行匹配
38         connected+=1                                        #成功连接数加一
39         for i in range(len(temp0)):
40             if temp0[i] not in list:                        #新链接储存起来
41                 list.append(temp0[i])
42         for j in range(num,len(list)):
43             print(list[j])                                  #输出这次新获得的链接
44             fo.writelines(list[j])
45             fo.writelines("\n")
46         num=len(list)
47         print("\n")
48         fo.writelines("\n\n")
49     except:
50         print("{}连接或解析失败\n\n".format(list[x]))
51         fo.writelines("{}连接或解析失败\n\n\n".format(list[x]))
52         x+=1
53     else:
54         x+=1
55 else:
56     end=time.clock()
57     print("爬虫结束...!")
58     print("本次爬虫共爬过{}个网站,爬得{}个链接".format(connected,len(list)-1))
59     print("共耗时{:.3f}s".format(end-start))
60     fo.writelines("\n")
61     fo.writelines("爬虫结束...!")
62     fo.writelines("\n")
63     fo.writelines("本次爬虫共爬过{}个网站,爬得{}个链接".format(connected,len(list)-1))
64     fo.writelines("\n")
65     fo.writelines("共耗时{:.3f}s".format(end-start))

 

   这个爬虫的关键在于那个正则表达式:

1 patten=re.compile(r'https?://[^\\\'"\.].+?[^\\\'"](?:/|com|org|net|cn|cc|tv)'

   这句的意思是把那个正则表达式编译成正则表达式对象然后储存在patten变量里。

  而核心的正则表达式:https?://[^\\\'"\.].+?[^\\\'"](?:/|com|org|net|cn|cc|tv)

  是指匹配以http开头,可能有s(https),加上://,以/、com、org、net、cn、cc、tv结尾的链接

  中间的[^\\\'"\.]指http(s)://后面不能直接跟\ ' " .这四个符号

  .+?指非贪婪的匹配任何字符

  [^\\\'"]指在com等结尾之前不能出现\ ' "的符号

  这个表达式花了我很大力气写出来,而且匹配仍会有一定的出错率,目前还不知道有什么解决办法。

以上。

 

posted @ 2016-11-12 21:19  SteveHawk  阅读(384)  评论(0)    收藏  举报