参考资料html
代码实现(一): 用Python抓取指定页面python
1 #!/usr/bin/env python 2 #encoding:UTF-8 3 import urllib.request 4 5 url = "http://www.baidu.com" 6 data = urllib.request.urlopen(url).read() 7 data = data.decode('UTF-8') 8 print(data)
urllib.request是一个库, 隶属urllib. 点此打开官方相关文档. 官方文档应该怎么使用呢? 首先点刚刚提到的这个连接进去的页面有urllib的几个子库, 咱们暂时用到了request, 因此咱们先看urllib.request部分. 首先看到的是一句话介绍这个库是干什么用的:web
The urllib.request module defines functions and classes which help in opening URLs (mostly HTTP) in a complex world — basic and digest authentication, redirections, cookies and more.正则表达式
而后把咱们代码中用到的urlopen()函数部分阅读完.算法
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False)数组
重点部分是返回值, 这个函数返回一个 http.client.HTTPResponse 对象, 这个对象又有各类方法, 好比咱们用到的read()方法, 这些方法均可以根据官方文档的连接链过去. 根据官方文档所写, 我用控制台运行完毕上面这个程序后, 又继续运行以下代码, 以更熟悉这些乱七八糟的方法是干什么的。浏览器
>>> import urllib.request >>> a = urllib.request.urlopen('http://10.54.0.2/OAapp/WebObjects/OAapp.woa') >>> type(a) <class 'http.client.HTTPResponse'> >>> a.geturl() 'http://10.54.0.2/OAapp/WebObjects/OAapp.woa' >>> a.info() <http.client.HTTPMessage object at 0x7f390a3d4780> >>> a.getcode() 200
若是要抓取百度上面搜索关键词为Jecvay Notes的网页, 则代码以下cookie
1 #!/usr/bin/env python 2 #encoding:UTF-8 3 import urllib 4 import urllib.request 5 6 data={} 7 data['word']='Jecvay Notes' 8 9 url_values=urllib.parse.urlencode(data) 10 url="http://www.baidu.com/s?" 11 full_url=url+url_values 12 13 data=urllib.request.urlopen(full_url).read() 14 data=data.decode('UTF-8') 15 print(data)
data是一个字典, 而后经过urllib.parse.urlencode()来将data转换为 'word=Jecvay+Notes'的字符串, 最后和url合并为full_url, 其他和上面那个最简单的例子相同. 关于urlencode(), 一样经过官方文档学习一下他是干什么的. 经过查看网络
大概知道他是把一个通俗的字符串, 转化为url格式的字符串。数据结构
Python的队列
在爬虫程序中, 用到了广度优先搜索(BFS)算法. 这个算法用到的数据结构就是队列.
Python的List功能已经足够完成队列的功能, 能够用 append() 来向队尾添加元素, 能够用相似数组的方式来获取队首元素, 能够用 pop(0) 来弹出队首元素. 可是List用来完成队列功能实际上是低效率的, 由于List在队首使用 pop(0) 和 insert() 都是效率比较低的, Python官方建议使用collection.deque来高效的完成队列任务.
1 #!/usr/bin/env python 2 #encoding:UTF-8 3 from collections import deque 4 queue = deque(["Eric", "John", "Michael"]) 5 queue.append("Terry") # Terry 入队 6 print(queue) 7 queue.append("Graham") # Graham 入队 8 print(queue) 9 queue.popleft() # 队首元素出队 10 print(queue) 11 #输出: 'Eric' 12 queue.popleft() # 队首元素出队 13 #输出: 'John' 14 print(queue) # 队列中剩下的元素
Python的集合
在爬虫程序中, 为了避免重复爬那些已经爬过的网站, 咱们须要把爬过的页面的url放进集合中, 在每一次要爬某一个url以前, 先看看集合里面是否已经存在. 若是已经存在, 咱们就跳过这个url; 若是不存在, 咱们先把url放入集合中, 而后再去爬这个页面。
Python提供了set这种数据结构. set是一种无序的, 不包含重复元素的结构. 通常用来测试是否已经包含了某元素, 或者用来对众多元素们去重. 与数学中的集合论一样, 他支持的运算有交, 并, 差, 对称差.
建立一个set能够用 set() 函数或者花括号 {} . 可是建立一个空集是不能使用一个花括号的, 只能用 set() 函数. 由于一个空的花括号建立的是一个字典数据结构. 如下一样是Python官网提供的示例。
1 >>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'} 2 >>> print(basket) # 这里演示的是去重功能 3 {'orange', 'banana', 'pear', 'apple'} 4 >>> 'orange' in basket # 快速判断元素是否在集合内 5 True 6 >>> 'crabgrass' in basket 7 False 8 9 >>> # 下面展现两个集合间的运算. 10 ... 11 >>> a = set('abracadabra') 12 >>> b = set('alacazam') 13 >>> a 14 {'a', 'r', 'b', 'c', 'd'} 15 >>> a - b # 集合a中包含元素 16 {'r', 'd', 'b'} 17 >>> a | b # 集合a或b中包含的全部元素 18 {'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'} 19 >>> a & b # 集合a和b中都包含了的元素 20 {'a', 'c'} 21 >>> a ^ b # 不一样时包含于a和b的元素 22 {'r', 'd', 'b', 'm', 'z', 'l'}
其实咱们只是用到其中的快速判断元素是否在集合内的功能, 以及集合的并运算。
Requests Module
Requests 是 Python 界大名鼎鼎的一个网络库, 其设计哲学是为人类而设计, 因此他提供的功能都很是的人性化. 他的方便对我而言主要有两大点:
Requests 的方便之处不止这两点, 还提供了诸如标准登陆接口之类的功能, 咱们暂时用不上.
总而言之, 对于使用过 urllib 的咱们来讲, 用 requests 会感受咱们以前生活在石器时代. 第三方库的强大就在于这里, 这也是 Python 这么火的重要缘由.
BeautifulSoup Module
BeautifulSoup 大大方便了咱们对抓取的 HTML 数据的解析, 能够用tag, class, id来定位咱们想要的东西, 能够直接提取出正文信息, 能够全文搜索, 一样也支持正则表达式, 至关给力.
小试牛刀
咱们随便抓取一个页面, 而后用 soup 来解析一下试试他的威力:
1 >>> import requests 2 >>> from bs4 import BeautifulSoup 3 >>> response = requests.get("http://jecvay.com") 4 >>> soup = BeautifulSoup(response.text) 5 6 >>> print(soup.title.text) 7 Jecvay Notes - Good luck & Have fun 8 9 >>> print(soup.body.text) 10 改版策略: 技术博客的真正索引 11 12 上周, 我换掉了我博客的主题, 使用 BootStrap 框架本身写了一个. 在本身动手写博客主题以前, 13 我时常时不时到后台主题商店去翻一翻, 想要发现更好看的主题. 挑选有两种: 14 在一大堆展现面前, 快速浏览, 看到亮眼的就仔细看一看是否满意; 15 本身想好一个目标, 而后用筛选器(或者人肉)筛选出来. 16 阅读全文 >> (...省略若干) 17 18 >>> for x in soup.findAll("a"): 19 ... print(x['href']) 20 ... 21 http://jecvay.com/2015/02/the-real-index-of-tech-blog.html 22 http://jecvay.com/2015/02/the-real-index-of-tech-blog.html 23 http://jecvay.com/2015/01/wordpress-super-cache.html 24 http://jecvay.com/2015/01/learning-vps-3.html 25 http://jecvay.com/2015/01/nobot-anti-webspider.html 26 http://jecvay.com/2015/01/learning-vps-2.html 27 http://jecvay.com/2014/12/learning-vps-1.html 28 http://jecvay.com/2014/11/what-is-min-cut.html 29 http://jecvay.com/2014/11/compiler-makes-fast-build.html 30 /about-me 31 /archive
咱们十分轻松的得到了全文内容以及全部连接.
在上一篇文章中, 我尝试使用 urllib 和 re 获取了知乎登陆页面的 _xsrf 参数, 此次咱们经过这两个新的模块再试一次.
打开浏览器隐身模式, 打开知乎网, 来到登陆界面, 查看源代码, 搜索 xsrf 字样, 获得以下一行:
<input type="hidden" name="_xsrf" value="d4ff8d988193442a774bd0ccff336101"/>
因而咱们只要两行代码就能搞定:
1 >>> soup = BeautifulSoup(requests.get("http://www.zhihu.com").text) 2 >>> print(soup.find("input", {"name": "_xsrf"})['value']) 3 d4ff8d18b293442a764bd0ccff333601
第三方库就是这么好用!