from urllib.request import urlopen
import re
from bs4 import BeautifulSoup
html = urlopen("http://www.pythonscraping.com/pages/page3.html")
bsObj = BeautifulSoup(html, 'html.parser')
images = bsObj.find_all("img", {"src":re.compile("\.\.\/img\/gifts/img.*\.jpg")})
for image in images:
print(image["src"])
正则表达式常用符号:
a4e f!ne
正则表达式并非处处正则!
正则表达式的标准版(此处的版本)是基于 Perl 语法演变而来的。绝大多数主流编程语言都使用与之相同或近似的版本。但是,在其他语言中使用这些正则表达式时需要当心,否则可能会出问 题。有些语言,比如 Java ,其正则表达式就和 Python 不太一样。总之,遇 到问题时看文档!
附:正则表达式和BeautifulSoup
实例:
抓取的网页是 http://www.pythonscraping.com/pages/page3.html 。注意观察网页上有几个商品图片——它们的源代码形式如下:
如果我们想抓取所有图片的 URL 链接,非常直接的做法就是用
find_all("img")
抓取所有图片,对吗?但是,有个问题。除了那些明显“多余的”图片(比如,LOGO)之外,新式的网站里都有一些隐藏图片,用于网页布局留白和元素对齐的空白图片,以及一些不容易察觉到的图片标签。总之,你不能仅用商品图片来统计网页上所有的图片。而且网页的布局也可能会变化,或者,因为某些原因,我们不想通过图片在网页中的位置来查找标签。那么当你想抓取随机分布在网站里的某个元素或数据时,就会出现问题。例如,一些网页的最上面可能有一张商品图片,但是在另一些网页上没有。
解决这类问题的办法,就是直接定位那些标签来查找信息。在本例中,我们直接通过商品图片的文件路径来查找:
这段代码会打印出图片的相对路径,都是以
../img/gifts/img
开头,以.jpg
结尾,其结果如下所示:正则表达式可以作为 BeautifulSoup 语句的任意一个参数,让你的目标元素查找工作极具灵活性。
获取属性
前面已经介绍过如何获取和过滤标签,以及获取标签里的内容。
但是,在网络数据采集时你经常不需要查找标签的内容,而是需要查找标签属性。比如标签
<a>
指向的 URL 链接包含在href
属性中,或者<img>
标签的图片文件包含在src
属性中,这时获取标签属性就变得非常有用了。对于一个标签对象,可以用下面的代码获取它的全部属性:
要注意这行代码返回的是一个 Python 字典对象,可以获取和操作这些属性。比如要获取图片的资源位置
src
,可以用下面这行代码:附:Lambda表达式
例如,下面的代码就是获取有两个属性的标签:
这行代码会在 http://www.pythonscraping.com/pages/page3.html 找出下面的标签:
如果你愿意多写一点儿代码,那么在 BeautifulSoup 里用 Lambda 表达式选择标签,将是正则表达式的完美替代方案。
以上参考或摘自:《Web Scraping with Python》
再说Lambda表达式
Lambda 只是简单函数定义的一种简化写法;在
def
语句中定义的函数也可以像用 lambda 表达式定义的函数一样被传递或赋值给其他名称。def
形式实际上更为强大,因为它允许执行多条语句和使用标注。更多参考:https://www.w3schools.com/python/python_lambda.asp