爬虫

首先上爬虫的定义:网络爬虫是一种自动获取网页内容的程序,是搜索引擎的重要组成部分。

嗯,按照我的理解就是爬虫程序就是能够提取网页中信息的程序

我也是这两天才开始学爬虫,这篇教程参考了网上的很多资源,希望能给有需要的人以帮助。

在各位看官开始学习之前想向大家介绍几篇文章,请大家认真阅读,这样上手python爬虫就会事半功倍了。

1、如何入门Python爬虫 — from 知乎

2、你是如何开始能写python爬虫? — from 知乎

3、零基础自学用Python 3开发网络爬虫

我很大程度上是按照上面介绍的第三篇博客入门python爬虫的。

Python介绍

Python(英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/),是一种面向对象、直译式的计算机程序语言,具有近二十年的发展历史。它包含了一组功能完备的标准库,能够轻松完成很多常见的任务。它的语法简单,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。— 来自于维基百科

另外该篇博客适用于有高等语法基础(不需要必须是python)的朋友,没有语法基础的朋友可以去慕课网codecademy学习下

工欲善其事必先利其器

在学习python的过程中,不得不面临python 2.+python 3.+的选择,个人觉得既然是出于学习的目的,当然要学习新知识,因此我选择了python 3.4

个人使用体会:python3.+python2.+的基础上对包又进行了一些整合,语法略有些变化,可能因为现在我涉及的层面还比较浅,并未感觉两个版本之间有太大的不同。

可以通过官网安装python 3.4;附python官方文档

我们现在的目标是实现一个可以从一个链接开始爬取所有相关链接的爬虫

思路:

  • 1、从给定链接开始,维持一个待爬取队列,以及一个已访问链接集合

  • 2、每次从队列中弹出一条链接并打开,对于该链接对应页面,用正则表达式匹配页面内所有的链接,

  • 3、对这些链接进行判断,如果已经被爬虫爬过,则跳过,否则加入待爬取队列

  • 4、重复2,3步,直到队列为空,说明所有链接均已被爬取

话不多说,下面通过8个程序来学习python爬虫吧

python教程-1.1

python中使用#注释,多行注释使用快捷键Alt+3,消除多行注释使用快捷键Alt+4

下面这个小程序的功能是打开一个网页并读取网页源码

1
2
3
4
5
6
7
8
9
10
11
import urllib
import urllib.request
url = "http://baidu.com"
html = urllib.request.urlopen(url) #打开url链接
html = html.read().decode('utf-8') #以utf-8编码格式对所读取页面进行解码
print(html) #打印网页源码

python教程-1.2

使用下面这个程序实现python中我们需要的队列
deque的相关内容可参见C++或java中deque的定义

1
2
3
4
5
6
7
8
9
10
#利用deque模拟Queue
from collections import deque
queue = deque(["Eric", "John", "Michael"])
queue.append("Terry")
queue.append("Graham")
print(queue.popleft())
print(queue.popleft())
print(queue)

python教程-1.3

下面这个小程序是为了演示set功能,类似于数学中集合的定义,每个元素具有唯一性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#演示set功能
basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
print(basket)
print('orange' in basket)
print('crabgrass' in basket)
a = set('abracadabra')
b = set('alacazam')
print(a)
print(a-b)
print(a|b)
print(a&b)
print(a^b)

python教程-1.4

程序演示python中正则表达式应用

re.match(pattern, string, flags=0)实现按照pattern的模式匹配stringflags是附加标志位;

同理re.search(pattern, string, flags=0)实现搜索功能 ;

re.sub(pattern, string, flags=0)实现替换功能。

re.match()re.search()区别在于

  • 如果re.match()在匹配字符串开始的过程中失败就会终止匹配

  • re.search()则会从字符串开始到结尾尝试匹配

有不懂或者遗忘正则表达式的朋友请点这里:

flag含义:

1、 re.I 大小写不敏感

2、 re.L 本地化识别匹配

3、 re.M 多行匹配

4、 re.S 使.能够匹配换行符

5、 re.U 根据Unicode解析字符

另外也可以使用re.compile(pattern).findall(string)来查找所有匹配,会返回所有匹配结果,并且结果保存在列表中(后面会有具体的栗子)

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
#re.match(pattern, string, flags=0)
import re
line = "Cats are smarter than dogs"
matchObj = re.match(r'(.*) are (.*?) .*', line, re.M|re.I)
if matchObj:
print(matchObj.group())
print(matchObj.group(1))
print(matchObj.group(2))
else:
print("No match!!")
#演示python中正则表达式搜索应用
#re.search(pattern, string, flags=0)
matchObj = re.search(r'(.*) are (.*?) .*', line, re.M|re.I)
if matchObj:
print(matchObj.group())
print(matchObj.group(1))
print(matchObj.group(2))
else:
print("No match!!")
#演示python中正则表达式替换应用
#re.sub(pattern, repl, string, max=0)
phone = "2004-959-559 # This is Phone Number"
num = re.sub(r'#.*$', "", phone)
print("Phone Num : ", num)
num = re.sub(r'\D', "", phone)
print("Phone Num : ", num)

python教程-1.5

目标的实现:下面的程序即实现了我们开始要求的功能,当然想把所有链接都爬取是需要时间的。。。当你觉得不需要再爬的时候可以中断程序

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
#简单爬虫
import re
import urllib.request
import urllib
from collections import deque
queue = deque()
visited = set()
url = "http://www.baidu.com"
queue.append(url)
cnt = 0
while queue: #当队列不为空
url = queue.popleft()
visited |= {url} #加入visited集合中
print('I\'v got :' + str(cnt))
print('I\'m getting ' + url)
cnt += 1;
urlop = urllib.request.urlopen(url)
if 'html' not in urlop.getheader('Content-Type'): #避免爬取非网页url的链接,比如文件地址
continue
try:
data = urlop.read().decode('utf-8') #过滤掉不能正确读取的页面,避免程序异常中断
except:
continue
linkre = re.compile('href=\"(.+?)\"')
for x in linkre.findall(data):
if 'http' in x and x not in visited: #找出匹配后未访问过的链接
queue.append(x)
print('appending ---> ' + x)

以上就是该篇博客所有内容了,如有未尽兴的朋友,请移步:

1、python实战之爬取网站图片到本地

2、python实战之郑州大学GPA计算器