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中的if、else、elif语句用法简明讲解
Mar 11 Python
有趣的python小程序分享
Dec 05 Python
python学习笔记--将python源文件打包成exe文件(pyinstaller)
May 26 Python
利用Python将文本中的中英文分离方法
Oct 31 Python
python中时间模块的基本使用教程
May 14 Python
python elasticsearch环境搭建详解
Sep 02 Python
详解python播放音频的三种方法
Sep 23 Python
python反转列表的三种方式解析
Nov 08 Python
python和pywin32实现窗口查找、遍历和点击的示例代码
Apr 01 Python
Python文件时间操作步骤代码详解
Apr 13 Python
使用python处理题库表格并转化为word形式的实现
Apr 14 Python
keras自动编码器实现系列之卷积自动编码器操作
Jul 03 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 include的妙用,实现路径加密
2008/07/29 PHP
php生成二维码的几种方式整理及使用实例
2013/06/03 PHP
php数据类型判断函数有哪些
2013/09/23 PHP
再Docker中架设完整的WordPress站点全攻略
2015/07/29 PHP
分享php多功能图片处理类
2016/05/15 PHP
php利用gd库为图片添加水印
2016/11/09 PHP
php合并数组并保留键值的实现方法
2018/03/12 PHP
thinkphp5 + ajax 使用formdata提交数据(包括文件上传) 后台返回json完整实例
2020/03/02 PHP
麦鸡的TAB切换功能结合了javascript和css
2007/12/17 Javascript
QQ空间顶部折页撕开效果示例代码
2014/06/15 Javascript
jQuery带箭头提示框tooltips插件集锦
2014/11/17 Javascript
vue2实现移动端上传、预览、压缩图片解决拍照旋转问题
2017/04/13 Javascript
JS继承与闭包及JS实现继承的三种方式
2017/10/15 Javascript
面包屑导航详解
2017/12/07 Javascript
使用npm安装最新版本nodejs
2018/01/18 NodeJs
angular1配合gulp和bower的使用教程
2018/01/19 Javascript
JavaScript常见事件对象与操作实例总结
2019/01/05 Javascript
使用express获取微信小程序二维码小记
2019/05/21 Javascript
vue.js实现数据库的JSON数据输出渲染到html页面功能示例
2019/08/03 Javascript
IE11下CKEditor在Bootstrap Modal中下拉问题的解决
2019/09/25 Javascript
[04:03]辉夜杯主赛事 12月25日RECAP精彩回顾
2015/12/26 DOTA
python实现发送和获取手机短信验证码
2016/01/15 Python
Python实现视频下载功能
2017/03/14 Python
python3中set(集合)的语法总结分享
2017/03/24 Python
python利用xlsxwriter模块 操作 Excel
2020/10/14 Python
廉价连衣裙和婚纱礼服在线销售:Tbdress
2019/02/28 全球购物
英文简历中的自荐信范文
2013/12/14 职场文书
网络维护中文求职信
2014/01/03 职场文书
信用社员工先进事迹材料
2014/02/04 职场文书
家长对孩子的感言
2014/03/10 职场文书
出生医学证明书
2014/09/15 职场文书
公司授权委托书格式范文
2014/10/02 职场文书
离婚财产分隔协议书
2014/10/23 职场文书
2015年收银员个人工作总结
2015/04/01 职场文书
2015年反腐倡廉工作总结
2015/05/14 职场文书
2016年习主席讲话学习心得体会
2016/01/20 职场文书