抓取某安全公司升级包链接(python小白登天日记)

如果有大神路过,希望指出我描述种错误的部分,感激不尽。
他的工作是去别人公司给安全软件升级,比如如果客户公司版本号是1.1,最新版本号是10.0,他需要从1.2下载到10.0并且按顺序安装,这是他给我的链接:
<code>http://update.nsfocus.com/update/listAurora/v/5</code>
可以看到需要下载的东西确实挺多的,如果一个个点不是不能点完,但是这个正好可以用来练手,也挺简单的,不需要登录,

这一次我先上代码 版本2.7:

<blockquote>
from bs4 import BeautifulSoup#解析网页的模块
import re#正则模块
import urllib#网络请求模块
url = "http://update.nsfocus.com/update/listAurora/v/5"
page = urllib.urlopen(url)#请求页面
html = page.read()#获取页面内容
soup = BeautifulSoup(html,'html.parser')#将页面变成bs的一个对象,用来后面的解析
test = soup.find_all(attrs={'href':re.compile("/update/downloads/id/")})#利用正则找到 含有href这个属性,且href中包含"/update/downloads/id/"这块字符串的所有标签。
for a in test:#遍历下载链接
Furl = downloadUrl + a['href']
print Furl
urllib.urlretrieve(Furl,"code.zip")#开始下载,但是这一块是错误的
</blockquote>

先说BeautifulSoup,以下简称bs:

bs是用来解析接收到的网页的,解析约等于处理数据,咱们接受下来的网页有数不清的嵌套的标签,标签里有一堆乱七八糟的属性和值还有标签自己的content,我打印一下上面代码中的html大家一起鉴赏一下:
<blockquote>
<header class="header in-header">
<div class="n fixed">
<div class="language">
<div class="tools" id="tool">
<ul>
<li class="ui" style="z-index: 1000;">
<a id="language" class="ui2012" href="javascript:void(0)">语言</a>
<ul id="language_list" style="display:none;">
<li
fc8

<a target="_blank" href="http://www.nsfocus.com.cn/index.html">中文</a></li>
<li><a target="_blank" href="http://nsfocusglobal.com/">ENGLISH</a></li>
<li><a target="_blank" href="http://nsfocusglobal.com/?lang=ja">日本语</a></li>
</ul>
</li>
<li><a href="http://www.nsfocus.com.cn/aid/buyhelp.html" class="en">如何购买</a></li>
</ul>
</div>
</div>
<div class="topbox">
<div class="logo">

<a href="http://www.nsfocus.com.cn/index.html">
</a>
</div>
<div class="in_share bshare-custom">
<span class="phone">400-818-6868</span>
</div>
<ul class="nav fixed in-nav">
<li class="sy"><a class="shouye" href="http://www.nsfocus.com.cn/index.html">首页</a><div class="line sy"></div></li>
<li class="sy"><a href="http://www.nsfocus.com.cn/solutions/index.html">解决方案</a><div class="line"></div>
<dl>
<dd>
</blockquote>

本来想将这个html所有代码都拿过来大家鉴赏一下但是复制了一下,实在太大了,而且简书都给我提示了:

简书提示

上面放的代码只是极小极小一部分,这也是我们为什么要用bs模块来解析网页的原因,他会让我们解析这个网页的过程变得异常简单且流畅,下面说一下常用的方法:
<blockquote>soup = BeautifulSoup(html,'html.parser')</blockquote>
将html这个页面解析为一个bs的可操作对象。
BeautifulSoup()这个方法必填的两个参数,一个是html,也就是我们需要解析的网页,另一个是一个str,它代表的是什么呢?<a href = "http://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/index.html?highlight=html.parser">Beautiful Soup 4.4.0 文档</a>查看官方文档,发现它有详细的解释:

解析器 使用方法 优势 劣势
Python标准库 <code>BeautifulSoup(markup, "html.parser") </code> <p>Python的内置标准库</p><p>执行速度适中</p><p>文档容错能力强</p> Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差
Python标准库 <code>BeautifulSoup(markup, "lxml") </p>速度快<p>文档容错能力强 需要安装C语言库
lxml XML 解析器 <p><code>BeautifulSoup(markup, ["lxml-xml"])<p><code>BeautifulSoup(markup, "xml") <p>速度快<p>唯一支持XML的解析器 需要安装C语言库
html5lib <code>BeautifulSoup(markup, "html5lib") <p>最好的容错性<p>以浏览器的方式解析文档<p>生成HTML5格式的文档 <p>速度慢<p>不依赖外部扩展

上面的表格详细的写明白了这个字符串对应各种状况下应该填什么,优劣点都写的很清楚,我就不赘述了。

find_all方法简析:

<code>test = soup.find_all(attrs={'href':re.compile("/update/downloads/id/")})</code>
因为我要抓取当前页面的所有下载链接,所以我首先要找到含有这些链接的所有的网页标签,chrome打开链接,我用Mac的快捷键option+command+i 打开页面,然后shift+command+c 选中左边的显示内容,右边网页元素部分就会高亮对应的标签:

审查网页元素

可以看到右边代码高亮的部分如下:
<code><a href="/update/downloads/id/18501">aurora-051701.dat</a></code>
下一个下载链接所在的标签:
<code><a href="/update/downloads/id/18486">aurora-051700.dat</a></code>

看了几个标签之后总结一下规律,发现href中都含有"/update/downloads/id"这个字符串,但是这个字符串并不是完整的href值,所以我们用re.compile("/update/downloads/id")来表示完整的值。
接着说回来<a href = "http://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/index.html?highlight=find_all#find-all">find_all()</a>:
<code>find_all(name,attrs,recursive,string,**kwargs)</code>

<a>
<blockquote>

name 参数

name参数可以查找所有名字为 name的tag,字符串对象会被自动忽略掉.简单的用法如下:
<code>soup.find_all("title")# [<title>The Dormouse's story</title>]</code>
重申: 搜索 name参数的值可以使任一类型的 过滤器 ,字符c,正则表达式,列表,方法或是 <code>True.</code>

keyword 参数

如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索,如果包含一个名字为 id的参数,BeautifulSoup会搜索每个tag的”id”属性.
<code>soup.find_all(id='link2')# [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]</code>

如果传入 href 参数,Beautiful Soup会搜索每个tag的”href”属性:
<code>soup.find_all(href=re.compile("elsie"))# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]</code>

搜索指定名字的属性时可以使用的参数值包括 字符串 , 正则表达式 , 列表, True .
下面的例子在文档树中查找所有包含 id 属性的tag,无论 id 的值是什么:
<code>
soup.find_all(id=True)
[//<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
//<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
//<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]</code>

使用多个指定名字的参数可以同时过滤tag的多个属性:
<code>soup.find_all(href=re.compile("elsie"), id='link1')
// [<a class="sister" href="http://example.com/elsie" id="link1">three</a>]</code>

有些tag属性在搜索不能使用,比如HTML5中的 data-* 属性:
<code>data_soup = BeautifulSoup('<div data-foo="value">foo!</div>')data_soup.find_all(data-foo="value")
// SyntaxError: keyword can't be an expression</code>

但是可以通过 find_all()方法的 attrs 参数定义一个字典参数来搜索包含特殊属性的tag:
<code>data_soup.find_all(attrs={"data-foo": "value"})
// [<div data-foo="value">foo!</div>]</code>

按CSS搜索

按照CSS类名搜索tag的功能非常实用,但标识CSS类名的关键字 class 在Python中是保留字,使用 class 做参数会导致语法错误.从BeautifulSoup的4.1.1版本开始,可以通过 class_ 参数搜索有指定CSS名的tag:
<code>soup.find_all("a", class_="sister")
// [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
//<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
//<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]</code>

class_ 参数同样接受不同类型的 过滤器 ,字符串,正则表达式,方法或 True :
<code>soup.find_all(class_=re.compile("itl"))
//[<p class="title"><b>The Dormouse's story</b></p>]def has_six_characters(css_class): return css_class is not None and len(css_class) == 6soup.find_all(class_=has_six_characters)
//[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
//<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
//<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]</code>

tag的 class 属性是 多值属性 .按照CSS类名搜索tag时,可以分别搜索tag中的每个CSS类名:
<code>css_soup = BeautifulSoup('<p class="body strikeout"></p>')css_soup.find_all("p", class_="strikeout")
//[<p class="body strikeout"></p>]css_soup.find_all("p", class_="body")
//[<p class="body strikeout"></p>]</code>

搜索 class 属性时也可以通过CSS值完全匹配:
<code>css_soup.find_all("p", class_="body strikeout")# [<p class="body strikeout"></p>]</code>

完全匹配 class 的值时,如果CSS类名的顺序与实际不符,将搜索不到结果:
<code>soup.find_all("a", attrs={"class": "sister"})
//[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
//<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
//<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]</code>

string参数

通过 string 参数可以搜搜文档中的字符串内容.与 name 参数的可选值一样, string 参数接受 字符串 , 正则表达式 , 列表, True . 看例子:
<code>
soup.find_all(string="Elsie")
//[u'Elsie']soup.find_all(string=["Tillie", "Elsie", "Lacie"])
//[u'Elsie',u'Lacie',u'Tillie']
soup.find_all(string=re.compile("Dormouse"))
//[u"The Dormouse's story", u"The Dormouse's story"]
def is_the_only_string_within_a_tag(s):
""Return True if this string is the only child of its parent tag.""
return (s == s.parent.string)soup.find_all(string=is_the_only_string_within_a_tag)
//[u"The Dormouse's story", u"The Dormouse's story", u'Elsie', u'Lacie', u'Tillie', u'...']</code>

虽然 string参数用于搜索字符串,还可以与其它参数混合使用来过滤tag.Beautiful Soup会找到 .string 方法与 string 参数值相符的tag.下面代码用来搜索内容里面包含“Elsie”的a标签:
<code>soup.find_all("a", string="Elsie")# [<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>]</code>

limit参数

find_all()方法返回全部的搜索结构,如果文档树很大那么搜索会很慢.如果我们不需要全部结果,可以使用 limit 参数限制返回结果的数量.效果与SQL中的limit关键字类似,当搜索到的结果数量达到 limit 的限制时,就停止搜索返回结果.文档树中有3个tag符合搜索条件,但结果只返回了2个,因为我们限制了返回数量:
<code>soup.find_all("a", limit=2)
//[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
//<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]</code>

recursive参数

调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=<code>False.</code>
一段简单的文档:
<code><html> <head> <title> The Dormouse's story </title> </head>...</code>

是否使用 recursive参数的搜索结果:
<code>soup.html.find_all("title")# [<title>The Dormouse's story</title>]soup.html.find_all("title", recursive=False)# []</code>

这是文档片段
<code><html> <head> <title> The Dormouse's story </title> </head> ...</code>

<title>标签在 <html> 标签下, 但并不是直接子节点, <head> 标签才是直接子节点. 在允许查询所有后代节点时 Beautiful Soup 能够查找到 <title> 标签. 但是使用了 recursive=False 参数之后,只能查找直接子节点,这样就查不到 <title> 标签了.
Beautiful Soup 提供了多种DOM树搜索方法. 这些方法都使用了类似的参数定义. 比如这些方法: find_all(): name, attrs, text, limit. 但是只有 find_all() 和 find() 支持 recursive 参数.
</blockquote></a>

最后我用for遍历了一下所有标签,但是我们要的是标签里面href的值,所以要这么写:
<code>a['href']</code>
这样,我们就能打印出所有的链接,但是下载的部分那天是在太晚了,所以就没去看那个下载方法怎么使用,直接在网上找了一段代码,果然出错误了,咱们下次再说

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容