爬虫MOOC 第二周 入门

    xiaoxiao2021-03-25  102

    首先下载Beautiful Soup 4,然后解压安装,记得安装代码是

    python setup.py install

    这里要说明一点!!!很重要,我吃了一个多小时的亏。

    我把文件命名为 bs4.py

    这时候如果要from bs4 import ... 的话,就是直接读取文件本身,所以千万不要乱写脚本名字。如果把脚本名字改成 test.py 就可以了。

    真的烦人。

    然后就可以使用了。

    进入演示页面 http://python123.io/ws/demo.html

    测试 bs4 安装:

    from bs4 import BeautifulSoup 到这里如果没问题就搞定了。

    使用方法很简单,牢记这两行代码就行了。

    from bs4 import BeautifulSoup soup = BeautifulSoup('<p>data/p', 'html.parser') # 解析代码 =============================================================================

    HTML 代码大概是

    <html> <body> <p class="title"> ... </p> </body> </html> 这个样的,所以 bs4 库就是解析、遍历、维护“标签树”的功能库。

    其中

    <p> ... </p> 是 标签 tag,是成对出现的。

    <p class="title"> ... </p>p是标签的名称,p后面那个叫属性域,包含0个或者多个属性域。class就是一种属性,属性内容是 title。

    ============================================================

    bs4 的 HTML 解析器是 html.parser ,此外还有 lxml 和 html5lib 的解析器。

    这里主要用 HTML 解析器。

    这里假设已经获得了网页信息了,以下是一些命令:

    # -*- coding:utf-8 -*- from bs4 import BeautifulSoup soup = BeautifulSoup(demo, 'html.parser') # 解析代码 print 'title: ' print soup.title # 打印 title 标签 tag = soup.a # 获取 .a 标签,也就是链接标签 print'.a tag: ' print tag print soup.a.name #获取 a 标签的名字 print soup.a.parent.name # a 的父标签的名字 print soup.a.parent.parent.name # a 的父标签的父标签的名字 print tag.attrs # attrs 获得标签的属性(全部) print tag.attrs['class'] # 单独获得某个属性 print tag.attrs['href'] print type(tag.attrs) # 标签属性的类型(这里是字典) print type(tag) # 标签本身的类型(就是 tag 类型) print soup.a.string # a 标签的 string print soup.p # a 标签的 string 信息 'Basic Python' print soup.p.string # p 标签的 string 信息 print type(soup.p.string) # p 标签的 string 的类型 # tag 的 comment(注释)类型 newsoup = BeautifulSoup("<b><!--This is a comment--></b><p>This is not a comment</p>", "html.parser") print newsoup.b.string print type(newsoup.b.string) print newsoup.p.string print type(newsoup.p.string) # 注意 b 和 p 标签字符串的类型是不同的 =======================================================================

    基于 bs4 库的 html 提取方法

    首先回顾 demo 的写法:

    # -*- coding:utf-8 -*- # demo import requests from bs4 import BeautifulSoup r = requests.get("http://python123.io/ws/demo.html") demo = r.text print demo

    先说子节点的用法

    # 子节点 soup = BeautifulSoup(demo, 'html.parser') # 解析代码 print soup.head # head 标签 print soup.head.contents # head 的子节点是 title 标签,存在了一个列表中 print soup.body.contents # 同理,这是 body 的子节点标签 print len(soup.body.contents) # 表示 body 的子节点的数量,这里有五个 print soup.body.contents[1] # 这里输出的是第一个子节点 for child in soup.body.children: # 遍历儿子节点 print child for child in soup.body.descendants # 遍历子孙节点(课上说是 children ,感觉错了) print child 然后是父节点

    # 父节点 soup = BeautifulSoup(demo, 'html.parser') # 解析代码 print soup.title.parent # title 标签的父节点 print soup.html.parent # html 的父亲就是他自己 print soup.parent # soup 是一个特殊标签,他的父亲是空的 for parent in soup.a.parents: # 对 a 标签的所有先辈打印 if parent is None: print parent # 这里要注意 # 遍历的时候会遍历到 soup 本身,但是他是不存在 .name 信息的 else: print parent.name=============================================================================

    然后平行遍历

    # 平行遍历 soup = BeautifulSoup(demo, 'html.parser') # 解析代码 print soup.a.next_sibling # a 标签的下一个平行节点(不一定还是标签,也有可能是字符串) print soup.a.next_sibling.next_sibling # 再下一个平行节点 print soup.a.prebious_sibling # a 标签之前的一个平行节点 print soup.a.prebious_sibling.prebious_sibling # 再前一个,也许为空 print soup.a.parent for sibling in soup.a.next_siblings: # 遍历后续节点 print sibling for sibling in soup.a.prebious_siblings: # 遍历前续节点 print sibling 然后是输出

    # 输出 soup = BeautifulSoup(demo, 'html.parser') # 解析代码 print soup.prettify() # 带换行符,这个方法就是为文本标签内容添加换行符 print soup.a.prettify() # 单独打印 a 标签

    总结:

    到此就是BS4基本用法,接下来讲进一步用法。

    ==========================================================================

    HTML 信息标记有三大种类 :XML, JSON, YAML

    先有HTML,后有XML,它通过标签形式来构建信息。

    JSON:是有类型的键值对——key: value 的组合。比如 :

    "name": "北京大学"   

    "name": ["北京大学","理学院"]

    除了数字,需要双引号。

    YAML:采用无类型键值对——

    name:北京大学  

    注意没有双引号,需要的时候可以利用缩进表达从属,用 - 号表达并列。

    XML:扩展性好,但是繁琐

    JSON:适合 JavaScript,和XML比更简洁

    YAML:文本信息比例最高,可读性好。

    ================================================================

    ===========================================================

    信息提取方法:

    一、完整解析信息的标记形式,然后提取关键信息,比如bs4库的标签树遍历。

    二、无视标记形式,直接搜索关键信息。

    三、融合方法:结合形式解析和搜索方法,提取关键信息。

    from bs4 import BeautifulSoup soup = BeautifulSoup(demo, "html.parser") for link in soup.find_all('a'): # 查找 a 标签 print(link.get('href')) # 得到了内容,href 是属性。 记得之前的demo,再写一遍:

    # -*- coding:utf-8 -*- # demo import requests r = requests.get("http:/python123.io/ws/demo.html") demo = r.text print demo =====================================================

    现在介绍 find_all :

    # <>.find_all(name, attrs, recursive, string, **kwargs) # name: 对标签名称的检索字符串 # attrs: 对标签属性值的检索字符串,可标注属性检索 # recursive: 对标签的子孙搜索,默认为 True # string: <>...</> 中字符串区域的检索字符串 print soup.find_all('a'): # 查找 a 标签 print soup.find_all(['a','b']) # 找 a b 标签 for tag in soup.find_all(True): # True 会显示所有标签信息 print(tag.name) import re for tag in soup.find_all(re.compile('b')) # 返回的所有以 b 开头的信息 print tag.name print soup.find_all('p','course') # 查找了带有 course 属性的 p 标签 print soup.find_all(id = 'link1') # 属性中 id 域为 link1 的标签 print soup.find_all(id = 'link') # 属性中 id 域为 link 的标签 print soup.find_all(id = re.compile('link')) # 输出以 link 开头但是不全是 link 的信息 print soup.find_all('a', recursive = False) # 返回这里是一个空列表,说明儿子节点上面没有 a 标签 print soup.find_all(string = 'Basic Python') # 精确检索 Basic Python print soup.find_all(string = re.compile("Python")) # 使用正则,把带有 python 的字符串域全部检索

    以后会介绍正则库

    find_all() 函数 和 正则结合很好用。

    缩写:

    <tag>(..) 等价于 <tag>.find_all(..)

    soup(..) 等价于  soup.find_all(..)

    =========================================================================

    实战 http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html

    最好大学网的2016中国最好大学排名,这里我们要试着使用爬虫爬取。

    功能:

    输入:大学排URL

    输出:大学排名信息的屏幕输出(排名,大学,总分)

    路线:requests / BS4

    这个称为:定向爬虫

    先打开看看源代码。我们要看看这个页面的大学排名信息是动态的还是写在源代码中的,如果是源代码中就有的,那么可以爬取。

    实际上打开发现是写好了的,那么我们可以用爬虫爬取信息了。

    <tr class="alt"><td>1</td> <td><div align="left">清华大学</div></td> <td>北京市</td><td>95.9</td> 然后看一看网站的robots协议。

    404说明随便爬取。

    # -*- coding:utf-8 -*- # 爬取中国最好大学数据 import requests from bs4 import BeautifulSoup import bs4 def getHTMLText(url): # 从网络上获取大学排名网页内容 try: r = requests.get(url, timeout = 30) # 限定时间 30 秒 r.raise_for_status() # 有问题就产生异常 r.encoding = r.apparent_encoding # 编码 return r.text except: return "" # 否则返回空字符串 def fillUnivList(ulist, html ): # 提取网页内容中信息到合适的数据结构 # 注意这里的 "tbody"/"td"/"tr" 都是根据网页源代码来的 soup = BeautifulSoup(html, "html.parser") for tr in soup.find('tbody').children: # 遍历、查找在 tbody 中子标签中的 tr 标签,tr 包含大学信息 if isinstance(tr, bs4.element.Tag): # 检测 tr 标签类型,如果不是 bs4 库定义的 tag 类型,则过滤掉 tds = tr('td') # 把所有的 td 标签存为列表 tds ulist.append([tds[0].string, tds[1].string, tds[2].string]) # 把需要的 td 标签加入到 ulist def printUnivList(ulist, num ): # 利用数据结构展示并输出结果 tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}" # 注意 ":" 是引导符号,"3"是填充的字符,"^" 是居中对齐符号,"10"是宽度,最前面"0"、"1"、"2"是顺序 # chr 12288是中文空格变量 print (tplt.format("排名", "学校名称", "总分",chr(12288))) # format 方法格式化输出 for i in range(num): u = ulist[i] # 所有信息保存在 ulist 中 print (tplt.format(u[0], u[1], u[2],chr(12288))) # 格式化输出 def main(): # 主函数 uinfo = [] # 大学信息放在 uinfo 列表 url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html' html = getHTMLText(url) fillUnivList(uinfo, html) printUnivList(uinfo, 20) # 打印 20 所大学信息 main() 最后输出效果:

    个中的表格对齐很重要,请看图片和注释。

    转载请注明原文地址: https://ju.6miu.com/read-23399.html

    最新回复(0)