day 2-bs4数据解析学习总结

day 2-bs4数据解析

1. requests设置浏览器信息

import requests

418现象: 网页对应的服务器做了身份验证,必须浏览器才能返回数据。如果不是浏览器发送的请求就会返回418

解决方案:设置请求的请求头中的用户信息为一个浏览器信息

headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'
}
response = requests.get('https://movie.douban.com/top250', headers=headers)
if response.status_code == 200:
    print(response.text)

2. bs4基本用法

from bs4 import BeautifulSoup

1.创建网页对应的BeautifulSoup对象

BeautifulSoup(网页数据,解析器名称)

网页数据 - 需要解析的网页源代码

解析器 - lxml

html = open("data.html', encoding='utf-8').read()
soup = BeautifulSoup(html,'lxml')

2.获取标签

soup对象.select(css选择器) - 在整个网页中,获取css选择器选中的所有标签,返回值是列表,列表中的元素是标签对象
soup对象.select_one(css选择器) - 获取css选择器选中的标签中的第一个标签,返回值是标签对象

标签对象.select(css选择器) - 在指定标签中,获取css选择器选中的所有标签,返回值是列表,列表中的元素是标签对象
标签对象.select_one(css选择器) - 在指定标签中,获取css选择器选中的标签中的第一个标签,返回值是标签对象

result = soup.select('p')
print(result)

result = soup.select_one('p')
print(result)

# 获取所有商品的价格标签
result = soup.select('.goods_list .price')
print(result)

# 案例1:获取第一个商品的价格标签
# 方法1:
result = soup.select_one('.goods_list .price')
print(result)

# 方法2:
result = soup.select('.goods_list .price')[0]
print(result)


# 案例2:获取第二个商品的价格标签
# 方法1:
result = soup.select('.goods_list .price')[1]
print(result)

# 方法2
result = soup.select_one('.goods_list>li:nth-child(2)>.price')
print(result)

3.获取标签内容、获取标签属性

a = soup.select_one('div.c1>a')
1)获取标签内容: 标签对象.text
print(a.text)
2)获取标签属性:标签对象.attrs[属性名]
print(a.attrs['href'])
print(a.attrs['target'])
# 练习1:获取所有课程的名字
names_p = soup.select('.course_list .name')
course_names = [x.text for x in names_p]
print(course_names)

# 练习2:获取第二个课程的价格
price_p = soup.select_one('.course_list>li:nth-child(2)>.price')
print(price_p.text)


# 练习3:获取所有的课程以及对应的价格
# 方法1:
prices_p = soup.select('.course_list .price')
course_prices = [x.text for x in prices_p]

times_p = soup.select('.course_list span')
course_times = [x.text for x in times_p]
#
# # ['数据分析', '前端开发', 'java后端']
# # ['20000', '22000', '23000']
# # ['22周', '23周', '23周']
# #[{'name':'数据分析, 'price': '20000','time': '22周'}, {'name':'前端开发, 'price': '22000','time': '23周'}, ...]
result = map(lambda i1, i2, i3: {'name': i1, 'price': i2, 'time': i3}, course_names, course_prices, course_times)
print(list(result))

# 方法2:
courses_li = soup.select('.course_list>li')
all_course = []

for li in courses_li:
    name = li.select_one('.name').text
    price = li.select_one('.price').text
    time = li.select_one('span').text
    all_course.append({'name': name, 'price': price, 'time': time})

print(all_course)

3. bs4豆瓣电影解析

import requests
from bs4 import BeautifulSoup
import csv
from re import sub
# 1. 获取网络
def get_net_data(start):
    headers = {
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36'
    }
    response = requests.get(f'https://movie.douban.com/top250?start={start}&filter=', headers=headers)
    if response.status_code == 200:
        return response.text
    else:
        return None
# 2. 解析数据
def analysis_data(html):
    soup = BeautifulSoup(html, 'lxml')
    all_li = soup.select('.grid_view>li')       # 所有电影对应的li标签的列表
    all_movie = []
    for li in all_li:
        name = li.select_one('.hd>a>span').text
        info = li.select_one('.bd>p').text.strip().split('\n')[1].strip()
        info = sub(r'\s+', '', info).split('/')
        time = info[0]
        country = info[1]
        f_type = info[-1]
        score = li.select_one('.rating_num').text
        comment_count = li.select_one('.star>span:nth-child(4)').text[:-3]
        all_movie.append({
            '名称': name,
            '评分': score,
            '评论人数': comment_count,
            '国家': country,
            '上映时间': time,
            '类型': f_type
        })

    with open('files/豆瓣电影.csv', 'a', encoding='utf-8', newline='') as f:
        writer = csv.DictWriter(f, ['名称', '评分', '评论人数', '国家', '上映时间', '类型'])
        if start == 0:
            writer.writeheader()
        writer.writerows(all_movie)


if __name__ == '__main__':
    for start in range(0, 226, 25):
        data = get_net_data(start)
        analysis_data(data)
        print('一页数据获取成功!', start//25)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值