python3-简单网页爬虫

获取网页标题

首先,我们要知道浏览器是要和服务器交互数据的,服务器发送html的文件被浏览器获取,我们要的就是这个htm,python和其他语言一样,都可以直接获取
需要这个包下的urlopen函数,urlopen用来打开并读取一个从网络获取的远程对象,它是一个很强强大的库(可以读取html,图像,或者其他文件流)

from urllib.request import urlopen

然后就是创建html对象

html=urlopen("网址")
print(html.read())

这样输出的是整个html的代码
但是这样的肯定不是我们想要的,接下来如果要继续处理html文件,就要使用一个第三方库:BeautifulSoup也叫bs4,因为我是使用pycharm编程的,这里就只写pycharm的导入方法
打开pycharm的file->settings
在这里插入图片描述
进入project interpreter页面点加号+,然后搜索bs4,电机install package等待下载完成就好了
在这里插入图片描述
返回上一页面可以看到bs4已经导入了
在这里插入图片描述
接下来就让我们试一下bs4是否已经能正常使用
写下这一段代码

from urllib.request import urlopen
from bs4 import BeautifulSoup
html=urlopen("http://www.pythonscraping.com/pages/page1.html")
bsObj=BeautifulSoup(html.read(),features="html.parser")#获取html内容位BeautifulSoup类型
print(bsObj.title)#输出title标签

可以看到结果:输出了页面标题
在这里插入图片描述
当然,一般情况不可能这么顺利,可能会出现404,或者url的错误,所以我们需要处理一下这两个异常,
再把上面的代码写成一个函数,于是乎,上面的代码可以变成这样:

from urllib.request import urlopen
from urllib.error import *
from bs4 import BeautifulSoup

# 获取标题
def getTitle(url):
    try:
        html=urlopen(url)
    except(HTTPError,URLError)as e:
        return None
    try:
        bsObj=BeautifulSoup(html.read(),features="html.parser")
        title=bsObj.html.h1
    except AttributeError as e:
        return None
    return title
title=getTitle("http://www.pythonscraping.com/pages/page1.html")
if title==None:
    print("Title cold not found")
else:
    print(title)

根据css筛选内容

我们知道,一个网页同一标签可能有很多,所以需要筛选,而基本上现在网页都有层叠样式表的存在,这一存在可以说是大大方便了爬虫的使用,因为我们可以用Bs4对同一标签不同的层叠样式表进行筛选
http://www.pythonscraping.com/pages/warandpeace.html
打开这个网站,这是一部小说,里面的人名是绿色的,对话是红色的在这里插入图片描述
接下来我们要用py获取全部的人名下来,检查,可以看到其中一个人名的属性是span class=“green”
在这里插入图片描述

在这里插入图片描述
好的知道了这些信息就要开始写代码了
代码和上面的相似,不过我们使用了findAll,bsObj.findAll(tagName,tagAttributes)可以获取页面中指定标签
然后获取人名列表后存到namelist’里循环打印

from urllib.request import urlopen
from bs4 import BeautifulSoup
html=urlopen("http://www.pythonscraping.com/pages/warandpeace.html")
bsObj=BeautifulSoup(html.read(),features="html.parser")
nameList=bsObj.findAll("span",{"class":"green"})
for i in nameList:
    print(i.get_text())

运行结果:在这里插入图片描述
这里的i.get_text()是获取标签内的内容,把标签本身删掉了,如果直接打印i的话:会保留标签信息:
在这里插入图片描述

BeautifulSoup里的find()和findAll()

BeautifulSoup里的find()和findAll()函数是非常常用的,他们可以轻松过滤html的标签,查找标签组或整个标签。他们的参数:

   findAll(tag,attributes,recursive,text,limit,keywords)
   find(tag,attributes,recursive,keywords)

虽然参数挺多的,但是我们用的时候一般都是前两个参数tag和attributes

标签参数tag参数前面已经使用过了,你可以穿一个或多个标签的名称组成的python列表,比如:返回h标题

.findAll({"h1","h2","h3","h4"})

属性参数attributes是对应的标签的若干属性和属性值,比如获取span标签的green和red的

.findAll("span",{"class":{"green","red"}})

第三个参数recursive是递归参数他是一个bool类型的变量,他表示你想抓取html文档结构里多少层信息?如果设置为true,findAll会查找所有的子标签,如果设置为false,则只会查找一级标签,默认值是true。一般情况我们默认就好,如果你对抓取速度有要求且十分了解自己想抓的具体位置,那时候可以设置参数。

第四个text是文本参数,也适用于筛选标签的,不同的是它筛选的不是标签的属性,而是标签内部的内容也就是文本,比如我们要查网页中包含“the prince”内容的标签数量,之前的代码可以换成下面这个/

namelist=bsObj.findAll(text="the prince");
print(len(namelist))

limit属性只用于findAll方法,

keyword属性可以让你选择具有置顶数的的标签,比如:

allText=bsObj.findAll(id=="text")
print(allText[0].get_text())

很显然这个功能我们可以用之前的方法实现,比如下面这两行代码功能是一样的:

bsObj.findAll(id="text")
bsObj.findAll("",{"id":"text"})

导航树

处理子节点

介绍完了根据标签名称和标签属性查找,接下来介绍根据标签在文档中的位置查找标签,如果我们确切的知道一个标签的位置就可以这么查找:
查找第一个div标签内的img属性列表

bsObj.div.findAll("img")

如果想找所有的子标签,可以用find函数的.childern方法比如http://www.pythonscraping.com/pages/page3.html
在这里插入图片描述
他的源码是这样的
在这里插入图片描述
如果我们想查找giftList这个表格内的所有属性就可以这么写:

from urllib.request import urlopen
from bs4 import BeautifulSoup
html=urlopen("http://www.pythonscraping.com/pages/page3.html")
bsObj=BeautifulSoup(html,features="html.parser")
for chile in bsObj.find("table",{"id":"giftList"}).children:
    print(chile)

这段代码会打印所有的数据行,如果改用descendants函数而不是children函数,那么就会有更多的标签打印出来,包括img标签span标签以及每个td标签。就是说children()只包含直接子节点,而descendants()则是会递归查找子孙节点

处理兄弟标签

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值