这一回, 开始用Python将伪代码中的所有部分实现. 由于文章的标题就是"零基础", 因此会先把用到的两种数据结构队列和集合介绍一下. 而对于"正则表达式"部分, 限于篇幅不能介绍, 但给出我比较喜欢的几个参考资料.

Python的队列

在爬虫程序中, 用到了广度优先搜索(BFS)算法. 这个算法用到的数据结构就是队列.

Python的List功能已经足够完成队列的功能, 可以用 append() 来向队尾添加元素, 可以用类似数组的方式来获取队首元素, 可以用 pop(0) 来弹出队首元素. 但是List用来完成队列功能其实是低效率的, 因为List在队首使用 pop(0) 和 insert() 都是效率比较低的, Python官方建议使用collection.deque来高效的完成队列任务.

1
2
3
4
5
6
7
8
9
10

from collections import deque
queue = deque(["Eric", "John", "Michael"])
queue.append("Terry")           # Terry 入队
queue.append("Graham")          # Graham 入队
queue.popleft()                 # 队首元素出队
#输出: 'Eric'
queue.popleft()                 # 队首元素出队
#输出: 'John'
queue                           # 队列中剩下的元素
#输出: deque(['Michael', 'Terry', 'Graham'])

(以上例子引用自官方文档)

Python的集合

在爬虫程序中, 为了不重复爬那些已经爬过的网站, 我们需要把爬过的页面的url放进集合中, 在每一次要爬某一个url之前, 先看看集合里面是否已经存在. 如果已经存在, 我们就跳过这个url; 如果不存在, 我们先把url放入集合中, 然后再去爬这个页面.

Python提供了set这种数据结构. set是一种无序的, 不包含重复元素的结构. 一般用来测试是否已经包含了某元素, 或者用来对众多元素们去重. 与数学中的集合论同样, 他支持的运算有交, 并, 差, 对称差.

创建一个set可以用 set() 函数或者花括号 {} . 但是创建一个空集是不能使用一个花括号的, 只能用 set() 函数. 因为一个空的花括号创建的是一个字典数据结构. 以下同样是Python官网提供的示例.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket)                      # 这里演示的是去重功能
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket                 # 快速判断元素是否在集合内
True
>>> 'crabgrass' in basket
False
>>> # 下面展示两个集合间的运算.
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                                  
{'a', 'r', 'b', 'c', 'd'}
>>> a - b                              # 集合a中包含元素
{'r', 'd', 'b'}
>>> a | b                              # 集合a或b中包含的所有元素
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b                              # 集合a和b中都包含了的元素
{'a', 'c'}
>>> a ^ b                              # 不同时包含于a和b的元素
{'r', 'd', 'b', 'm', 'z', 'l'}

其实我们只是用到其中的快速判断元素是否在集合内的功能, 以及集合的并运算.

Python的正则表达式

在爬虫程序中, 爬回来的数据是一个字符串, 字符串的内容是页面的html代码. 我们要从字符串中, 提取出页面提到过的所有url. 这就要求爬虫程序要有简单的字符串处理能力, 而正则表达式可以很轻松的完成这一任务.

参考资料

  • 正则表达式30分钟入门教程
  • w3cschool 的Python正则表达式部分
  • Python正则表达式指南

虽然正则表达式功能异常强大, 很多实际上用的规则也非常巧妙, 真正熟练正则表达式需要比较长的实践锻炼. 不过我们只需要掌握如何使用正则表达式在一个字符串中, 把所有的url都找出来, 就可以了. 如果实在想要跳过这一部分, 可以在网上找到很多现成的匹配url的表达式, 拿来用即可.

Python网络爬虫Ver 1.0 alpha

有了以上铺垫, 终于可以开始写真正的爬虫了. 我选择的入口地址是Fenng叔的Startup News, 我想Fenng叔刚刚拿到7000万美金融资, 不会介意大家的爬虫去光临他家的小站吧. 这个爬虫虽然可以勉强运行起来, 但是由于缺乏异常处理, 只能爬些静态页面, 也不会分辨什么是静态什么是动态, 碰到什么情况应该跳过, 所以工作一会儿就要败下阵来.

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

import re
import urllib.request
import urllib
from collections import deque
queue = deque()
visited = set()
url = 'http://news.dbanotes.net'  # 入口页面, 可以换成别的
queue.append(url)
cnt = 0
while queue:
  url = queue.popleft()  # 队首元素出队
  visited |= {url}  # 标记为已访问
  print('已经抓取: ' + str(cnt) + '   正在抓取 <---  ' + url)
  cnt += 1
  urlop = urllib.request.urlopen(url)
  if 'html' not in urlop.getheader('Content-Type'):
    continue
  # 避免程序异常中止, 用try..catch处理异常
  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('加入队列 --->  ' + x)

这个版本的爬虫使用的正则表达式是

1
'href="(.+?)"'

所以会把那些.ico或者.jpg的链接都爬下来. 这样read()了之后碰上decode('utf-8')就要抛出异常. 因此我们用getheader()函数来获取抓取到的文件类型, 是html再继续分析其中的链接.

1
2

if 'html' not in urlop.getheader('Content-Type'):
    continue

但是即使是这样, 依然有些网站运行decode()会异常. 因此我们把decode()函数用try..catch语句包围住, 这样他就不会导致程序中止. 程序运行效果图如下:

下回预告

爬虫是可以工作了, 但是在碰到连不上的链接的时候, 它并不会超时跳过. 而且爬到的内容并没有进行处理, 没有获取对我们有价值的信息, 也没有保存到本地. 下次我们可以完善这个alpha版本.

原文出处: Jecvay Notes (@Jecvay)

转载于:https://www.cnblogs.com/bfyin/p/6376720.html

零基础自学用Python 3开发网络爬虫(二): 用到的数据结构简介以及爬虫Ver1.0 alpha...相关推荐

  1. 零基础自学用Python 3开发网络爬虫(一)

    原文出处: Jecvay Notes (@Jecvay) 由于本学期好多神都选了Cisco网络课, 而我这等弱渣没选, 去蹭了一节发现讲的内容虽然我不懂但是还是无爱. 我想既然都本科就出来工作还是按照 ...

  2. 【GIS人必学】零基础学习ArcGIS Python脚本开发训练营来了

    Python作为一种高级程序设计语言,凭借其简洁.易读及可扩展性日渐成为程序设计领域备受推崇的语言.ArcGIS软件由于其面向地理问题的科学理念,不断创新的技术方法,已在国内外市场占据了主导地位.Py ...

  3. python零基础自学教材-python萌新:从零基础入门到放弃

    原标题:python萌新:从零基础入门到放弃 不管是在什么领域,自学者都占绝大多数,你说自学可以吗?可以,没问题的,只需要你具备以下几点最基础的能力: 第一点:天赋.对于python而言其实是非常需要 ...

  4. 0基础学python做什么工作好-零基础自学多久Python可以找什么工作

    虽说很多都想自己学Python,然后找相关的工作,那么自学Python可以找什么工作呢?另外,学多久Python可以找工作.对Python,要掌握哪些知识才能找到好工作呢?今天跟智连代理一起去了解一下 ...

  5. python零基础自学教材-Python零基础入门到精通自学视频教程

    最近,网上流传一组<人工智能实验教材>的图片,照片火起来的原因是教材是为幼儿园的小朋友们设计的Python被列入小学.初高中教材已不是新鲜事,现在又成功"打入"了幼儿园 ...

  6. 某化大学,教授亲自手把手,从零基础交我们Python利用开发公众号

    在一般的使用中,我们可以通过设置关键字实现一些基本的自动回复功能,但是这样的关键字回复远远不能满足我们的实际需求,比如我们要实现一个查快递的功能,必然是要通过调用快递接口对不同用户的不同输入给出不同的 ...

  7. python多久学会自学-零基础自学Python多久可以找工作?

    零基础自学Python多久可以找工作?零基础自学3个月很难找到工作.如果全职学习Python的话,学习6个的时间,不一定能达到找到工作的水平,掌握项目经验还需要更久,达到企业需要的岗位要求还需要多练习 ...

  8. 零基础学python用什么书-零基础自学python3 好用的入门书籍推荐

    零基础自学python3 好用的入门书籍推荐,博学谷小班整理了六本数,推荐阅读 <Python for data analysis>.<Python数据分析与挖掘实战>.< ...

  9. 如何学好python基础_零基础如何学好Python开发?

    作为一个零基础小白想学好Python开发应该先确定明确目标.做好学习Python系统规划.选择适合的开发工具.进阶提升学习规划.多练多看加深对Python程序的理解,想入门一门编程语言就需要不断的进行 ...

  10. 0基础学python做什么工作好-零基础自学Python多久可以找工作?

    零基础自学Python多久可以找工作?零基础自学3个月很难找到工作.如果全职学习Python的话,学习6个的时间,不一定能达到找到工作的水平,掌握项目经验还需要更久,达到企业需要的岗位要求还需要多练习 ...

最新文章

  1. Ubuntu 18 snap 占用 100%,卸载 snap
  2. lhgdialog 4.2.0 正式版发布
  3. Lint found fatal errors while assembling a release target
  4. 基于MATLAB的RSSI定位算法仿真
  5. 谋定5G+工业互联网-陈肇雄:经信研究体系化应用部署规划
  6. Docverter – 文本文件轻松转换为 PDF,Docx 和 ePub 文件
  7. Taro+react开发(100):问答模块07适配
  8. 利用类定义一个指针会调用默认构造函数吗_C++的拷贝构造函数
  9. WordPress-Lolimeow佛系简约主题 v1.6
  10. PostgreSQL如何拼接字符串
  11. linux下游戏制作工具,在Linux下可用Wine安装和运行D5Power游戏制作工具、蜂窝助手...
  12. GitHub桌面版 Github Desktop 下载
  13. 服务器CRT显示不全,CRT显示器显示画面不正常常见原因揭密
  14. icm20602姿态解算
  15. 中英文数字混合字符串排序js
  16. 闽江学院计算机毕设,闽江学院软件学院关于2017届毕业论文答辩有关事项的通知...
  17. 实时视频通话超低延迟架构的思考与实践
  18. python调用rarfile进行解压rar压缩包时,报了如下错误
  19. 42招健脑秘笈——必看
  20. plsr matlab,matlab中的偏最小二乘回归(PLSR)和主成分回归(PCR)

热门文章

  1. Resources.resx 未将对象引用设置到对象的实例
  2. 常见排序算法:归并排序
  3. 破解电信光猫RG2010-CA超级管理员账号
  4. YouTube架构学习
  5. 黑客,计算机革命的英雄!
  6. Linux爆本地提权漏洞 请立即更新udev程序
  7. 洛谷P2939 [USACO09FEB]改造路Revamping Trails(最短路)
  8. js批量向html容器内的元素赋值
  9. Python之socketserver源码分析
  10. Android4开发入门经典 之 第四部分:用户界面