java soup_BeautifulSoup 使用

测试页面地址

下载网页

import requests

url = 'https://reeoo.com/'

with open('web.html', encoding='utf8', mode='w+') as f:

f.write(requests.get(url).text)

构造soup对象测试输出

from bs4 import BeautifulSoup

with open('web.html', encoding='utf8', mode='r') as f:

soup = BeautifulSoup(f.read(), 'html.parser')

print(soup.title)

Reeoo - Web design inspiration and website gallery

Tag

Tag对象与HTML原生文档中的标签相同,可以直接通过对应名字获取

from bs4 import BeautifulSoup

with open('web.html', encoding='utf8', mode='r') as f:

soup = BeautifulSoup(f.read(), 'html.parser')

print(soup.title)

print(soup.meta)

Reeoo - Web design inspiration and website gallery

Name

通过Tag对象的name属性,可以获取到标签的名称

print(soup.title.name)

print(soup.meta.name)

title

meta

Attributes

一个tag可能包含很多属性,如id、class等,操作tag属性的方式与字典相同。

...

  • 也可以把中间的一些节点省略,结果也一致

    tag = soup.article.li

    通过 . 属性只能获取到第一个tag,若想获取到所有的 li 标签,可以通过 find_all() 方法

    ls = soup.article.div.ul.find_all('li')

    获取到的是包含所有li标签的列表。

    tag的 .contents 属性可以将tag的子节点以列表的方式输出:

    tag = soup.article.div.ul

    contents = tag.contents

    打印 contents 可以看到列表中不仅包含了 li 标签内容,还包括了换行符 '\n'

    过tag的 .children 生成器,可以对tag的子节点进行循环

    tag = soup.article.div.ul

    children = tag.children

    print children

    for child in children:

    print child

    可以看到 children 的类型为

    .contents 和 .children 属性仅包含tag的直接子节点,若要遍历子节点的子节点,可以通过 .descendants 属性,方法与前两者类似,这里不列出来了。

    父节点

    通过 .parent 属性来获取某个元素的父节点,article 的 父节点为 body。

    tag = soup.article

    print tag.parent.name

    # body

    或者通过 .parents 属性遍历所有的父辈节点。

    tag = soup.article

    for p in tag.parents:

    print p.name

    兄弟节点

    .next_sibling 和 .previous_sibling 属性用来插叙兄弟节点,使用方式与其他的节点类似。

    文档树的搜索

    对树形结构的文档进行特定的搜索是爬虫抓取过程中最常用的操作。

    find_all()

    find_all(name , attrs , recursive , string , ** kwargs)

    name 参数

    查找所有名字为 name 的tag

    soup.find_all('title')

    # [

    Reeoo - web design inspiration and website gallery]

    soup.find_all('footer')

    # [\n

    \n

    ...

    \n]

    keyword 参数

    如果指定参数的名字不是内置的参数名(name , attrs , recursive , string),则将该参数当成tag的属性进行搜索,不指定tag的话则默认为对所有tag进行搜索。

    如,搜索所有 id 值为 footer 的标签

    soup.find_all(id='footer')

    # [\n

    \n

    ...

    \n]

    加上标签的参数

    soup.find_all('footer', id='footer')

    # [\n

    \n

    ...

    \n]

    # 没有id值为'footer'的div标签,所以结果返回为空

    soup.find_all('div', id='footer')

    # []

    获取所有缩略图的 div 标签,缩略图用 class 为 thumb 标记

    soup.find_all('div', class_='thumb')

    这里需要注意一点,因为 class 为Python的保留关键字,所以作为参数时加上了下划线,为“class_”。

    指定名字的属性参数值可以包括:字符串、正则表达式、列表、True/False。

    True/False

    是否存在指定的属性。

    搜索所有带有 target 属性的标签

    soup.find_all(target=True)

    搜索所有不带 target 属性的标签(仔细观察会发现,搜索结果还是会有带 target 的标签,那是不带 target 标签的子标签,这里需要注意一下。)

    soup.find_all(target=False)

    可以指定多个参数作为过滤条件,例如页面缩略图部分的标签如下所示:

    ...

...

搜索 src 属性中包含 reeoo 字符串,并且 class 为 lazy 的标签:

soup.find_all(src=re.compile("reeoo.com"), class_='lazy')

搜索结果即为所有的缩略图 img 标签。

有些属性不能作为参数使用,如 data-**** 属性。在上面的例子中,data-original 不能作为参数使用,运行起来会报错,SyntaxError: keyword can't be an expression*。

attrs 参数

定义一个字典参数来搜索对应属性的tag,一定程度上能解决上面提到的不能将某些属性作为参数的问题。

例如,搜索包含 data-original 属性的标签

print soup.find_all(attrs={'data-original': True})

搜索 data-original 属性中包含 reeoo.com 字符串的标签

soup.find_all(attrs={'data-original': re.compile("reeoo.com")})

搜索 data-original 属性为指定值的标签

soup.find_all(attrs={'data-original': 'http://media.reeoo.com/Bersi Serlini Franciacorta.png!page'})

string 参数

和 name 参数类似,针对文档中的字符串内容。

搜索包含 Reeoo 字符串的标签:

soup.find_all(string=re.compile("Reeoo"))

打印搜索结果可看到包含3个元素,分别是对应标签里的内容

limit 参数

find_all() 返回的是整个文档的搜索结果,如果文档内容较多则搜索过程耗时过长,加上 limit 限制,当结果到达 limit 值时停止搜索并返回结果。

搜索 class 为 thumb 的 div 标签,只搜索3个

soup.find_all('div', class_='thumb', limit=3)

打印结果为一个包含3个元素的列表,实际满足结果的标签在文档里不止3个。

recursive 参数

find_all() 会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False。

find()

find(name , attrs , recursive , string , ** kwargs)

find() 方法和 find_all() 方法的参数使用基本一致,只是 find() 的搜索方法只会返回第一个满足要求的结果,等价于 find_all() 方法并将limit设置为1。

soup.find_all('div', class_='thumb', limit=1)

soup.find('div', class_='thumb')

搜索结果一致,唯一的区别是 find_all() 返回的是一个数组,find() 返回的是一个元素。

当没有搜索到满足条件的标签时,find() 返回 None, 而 find_all() 返回一个空的列表。

CSS选择器

Tag 或 BeautifulSoup 对象通过 select() 方法中传入字符串参数, 即可使用CSS选择器的语法找到tag。

语义和CSS一致,搜索 article 标签下的 ul 标签中的 li 标签

print soup.select('article ul li')

通过类名查找,两行代码的结果一致,搜索 class 为 thumb 的标签

soup.select('.thumb')

soup.select('[class~=thumb]')

通过id查找,搜索 id 为 sponsor 的标签

soup.select('#sponsor')

通过是否存在某个属性来查找,搜索具有 id 属性的 li 标签

soup.select('li[id]')

通过属性的值来查找查找,搜索 id 为 sponsor 的 li 标签

soup.select('li[id="sponsor"]')

其他

其他的搜索方法还有:

find_parents() 和 find_parent()

find_next_siblings() 和 find_next_sibling()

find_previous_siblings() 和 find_previous_sibling()

参数的作用和 find_all()、find() 差别不大,这里就不再列举使用方式了。这两个方法基本已经能满足绝大部分的查询需求。

还有一些方法涉及文档树的修改。对于爬虫来说大部分工作只是检索页面的信息,很少需要对页面源码做改动,所以这部分的内容也不再列举。

### 使用Python编写用于抓取Java项目信息的爬虫 #### 选择合适的技术栈 对于高效的数据抓取与分析,推荐采用如下技术栈[^4]: - **Python**: 编写爬虫程序和进行数据分析。 - **Requests**: 发送HTTP请求并获取网页内容。 - **BeautifulSoup**: 解析HTML页面并提取所需数据。 - **Selenium**: 抓取动态加载的内容(如果必要)。 #### 数据抓取过程实例化 假设目标是从特定平台上收集关于Java项目的评论或文档链接作为案例说明。这里以牛客网为例,该网站提供了大量编程语言的学习资源,包括Java项目评价等公开可访问的信息[^5]。 ```python import requests from bs4 import BeautifulSoup def fetch_java_project_reviews(base_url, pages=range(1, 3)): all_reviews = [] for page in pages: url = base_url.format(page) response = requests.get(url) soup = BeautifulSoup(response.text, 'html.parser') reviews_section = soup.find_all('div', class_='question-content') # 假设这是包含评论的部分 for review in reviews_section: text = review.get_text(strip=True) all_reviews.append(text) return all_reviews if __name__ == "__main__": urls_pattern = "https://www.nowcoder.com/ta/review-java/review?query=&asc=true&order=&page={}" java_reviews = fetch_java_project_reviews(urls_pattern) with open('java_reviews.txt', 'w+', encoding='utf8') as file: for item in java_reviews: file.write("%s\n" % item) ``` 这段代码展示了如何定义函数`fetch_java_project_reviews()`来遍历指定范围内的多个页面,并从中抽取有关Java项目的用户反馈。最终结果会被保存至本地文件中以便后续查看或进一步处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值