Python爬虫包 BeautifulSoup  递归抓取实例详解


Posted in Python onJanuary 28, 2017

Python爬虫包 BeautifulSoup  递归抓取实例详解

概要:

爬虫的主要目的就是为了沿着网络抓取需要的内容。它们的本质是一种递归的过程。它们首先需要获得网页的内容,然后分析页面内容并找到另一个URL,然后获得这个URL的页面内容,不断重复这一个过程。

让我们以维基百科为一个例子。

我们想要将维基百科中凯文·贝肯词条里所有指向别的词条的链接提取出来。

# -*- coding: utf-8 -*-
# @Author: HaonanWu
# @Date:  2016-12-25 10:35:00
# @Last Modified by:  HaonanWu
# @Last Modified time: 2016-12-25 10:52:26
from urllib2 import urlopen
from bs4 import BeautifulSoup

html = urlopen('http://en.wikipedia.org/wiki/Kevin_Bacon')
bsObj = BeautifulSoup(html, "html.parser")

for link in bsObj.findAll("a"):
  if 'href' in link.attrs:
    print link.attrs['href']

上面这个代码能够将页面上的所有超链接都提取出来。

/wiki/Wikipedia:Protection_policy#semi
#mw-head
#p-search
/wiki/Kevin_Bacon_(disambiguation)
/wiki/File:Kevin_Bacon_SDCC_2014.jpg
/wiki/San_Diego_Comic-Con
/wiki/Philadelphia
/wiki/Pennsylvania
/wiki/Kyra_Sedgwick

首先,提取出来的URL可能会有一些重复的

其次,有一些URL是我们不需要的,如侧边栏、页眉、页脚、目录栏链接等等。

所以通过观察,我们可以发现所有指向词条页面的链接都有三个特点:

  • 它们都在id是bodyContent的div标签里
  • URL链接不包含冒号
  • URL链接都是以/wiki/开头的相对路径(也会爬到完整的有http开头的绝对路径)
from urllib2 import urlopen
from bs4 import BeautifulSoup
import datetime
import random
import re

pages = set()
random.seed(datetime.datetime.now())
def getLinks(articleUrl):
  html = urlopen("http://en.wikipedia.org"+articleUrl)
  bsObj = BeautifulSoup(html, "html.parser")
  return bsObj.find("div", {"id":"bodyContent"}).findAll("a", href=re.compile("^(/wiki/)((?!:).)*$"))

links = getLinks("/wiki/Kevin_Bacon")
while len(links) > 0:
  newArticle = links[random.randint(0, len(links)-1)].attrs["href"]
  if newArticle not in pages:
    print(newArticle)
    pages.add(newArticle)
    links = getLinks(newArticle)

其中getLinks的参数是/wiki/<词条名称>,并通过和维基百科的绝对路径合并得到页面的URL。通过正则表达式捕获所有指向其他词条的URL,并返回给主函数。

主函数则通过调用递归getlinks并随机访问一条没有访问过的URL,直到没有了词条或者主动停止为止。

这份代码可以将整个维基百科都抓取下来

from urllib.request import urlopen
from bs4 import BeautifulSoup
import re

pages = set()
def getLinks(pageUrl):
  global pages
  html = urlopen("http://en.wikipedia.org"+pageUrl)
  bsObj = BeautifulSoup(html, "html.parser")
  try:
    print(bsObj.h1.get_text())
    print(bsObj.find(id ="mw-content-text").findAll("p")[0])
    print(bsObj.find(id="ca-edit").find("span").find("a").attrs['href'])
  except AttributeError:
    print("This page is missing something! No worries though!")

  for link in bsObj.findAll("a", href=re.compile("^(/wiki/)")):
    if 'href' in link.attrs:
      if link.attrs['href'] not in pages:
        #We have encountered a new page
        newPage = link.attrs['href']
        print("----------------\n"+newPage)
        pages.add(newPage)
        getLinks(newPage)
getLinks("")

一般来说Python的递归限制是1000次,所以需要人为地设置一个较大的递归计数器,或者用其他手段让代码在迭代1000次之后还能运行。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Python 相关文章推荐
Python爬取Coursera课程资源的详细过程
Nov 04 Python
Pythont特殊语法filter,map,reduce,apply使用方法
Feb 27 Python
总结网络IO模型与select模型的Python实例讲解
Jun 27 Python
微信跳一跳游戏python脚本
Apr 01 Python
TensorFlow高效读取数据的方法示例
Feb 06 Python
Python2实现的图片文本识别功能详解
Jul 11 Python
Python 字符串与二进制串的相互转换示例
Jul 23 Python
详解用pyecharts Geo实现动态数据热力图城市找不到问题解决
Jun 26 Python
python nmap实现端口扫描器教程
May 28 Python
Python for循环通过序列索引迭代过程解析
Feb 07 Python
能让Python提速超40倍的神器Cython详解
Jun 24 Python
浅谈Python中对象是如何被调用的
Apr 06 Python
python 编程之twisted详解及简单实例
Jan 28 #Python
详解python之简单主机批量管理工具
Jan 27 #Python
Python下的Softmax回归函数的实现方法(推荐)
Jan 26 #Python
在Django同1个页面中的多表单处理详解
Jan 25 #Python
Python heapq使用详解及实例代码
Jan 25 #Python
python3+PyQt5实现使用剪贴板做复制与粘帖示例
Jan 24 #Python
Python调用C++程序的方法详解
Jan 24 #Python
You might like
PHP如何利用P3P实现跨域
2013/08/24 PHP
学习php分页代码实例
2013/10/24 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(九)
2014/06/24 PHP
设置jsf的选择框h:selectOneMenu为不可编辑状态的方法
2014/01/07 Javascript
nodejs教程之环境安装及运行
2014/11/21 NodeJs
对JavaScript中this指针的新理解分享
2015/01/31 Javascript
功能强大的Bootstrap组件(结合js)
2016/08/03 Javascript
JavaScript输入框字数实时统计更新
2017/06/17 Javascript
JavaScript创建对象的七种方式(推荐)
2017/06/26 Javascript
Node.js+Express+MySql实现用户登录注册功能
2017/07/10 Javascript
让nodeJS支持ES6的词法----babel的安装和使用方法
2017/07/31 NodeJs
Js实现粘贴上传图片的原理及示例
2020/12/09 Javascript
使用python BeautifulSoup库抓取58手机维修信息
2013/11/21 Python
Python实现对excel文件列表值进行统计的方法
2015/07/25 Python
Python中list列表的一些进阶使用方法介绍
2015/08/15 Python
Python实现比较扑克牌大小程序代码示例
2017/12/06 Python
Sanic框架蓝图用法实例分析
2018/07/17 Python
Python WEB应用部署的实现方法
2019/01/02 Python
20行python代码实现人脸识别
2019/05/05 Python
Python Pandas 转换unix时间戳方式
2019/12/07 Python
pytorch载入预训练模型后,实现训练指定层
2020/01/06 Python
解决pycharm编辑区显示yaml文件层级结构遇中文乱码问题
2020/04/27 Python
Python 必须了解的5种高级特征
2020/09/10 Python
HTML5 Canvas 旋转风车绘制
2017/08/18 HTML / CSS
斯洛伐克香水和化妆品购物网站:Parfemy-Elnino.sk
2020/01/28 全球购物
韩国乐天网上商城:Lotte iMall
2021/02/03 全球购物
自1926年以来就为冰岛保持温暖:66°North
2020/11/27 全球购物
高级技校毕业生自荐信
2013/11/18 职场文书
房地产财务管理制度
2014/02/02 职场文书
遗嘱继承公证书
2014/04/09 职场文书
优秀教研组申报材料
2014/12/26 职场文书
雷锋的观后感
2015/06/10 职场文书
2015年卫生院健康教育工作总结
2015/07/24 职场文书
退休职工欢送会致辞
2015/08/01 职场文书
最新农村养殖致富:资金投入较低的创业项目有哪些?
2019/09/26 职场文书
SONY AN-LP1 短波有源天线放大器图
2022/04/05 无线电