超详细的Python爬虫案例讲解分享(附源码)

一、案例一:获取影片信息

访问豆瓣电影Top250,网址:https://movie.douban.com/top250?start=0 获取每部电影的中文片名、排名、评分及其对应的链接,按照“排名-中文片名-评分-链接”的格式显示在屏幕上。

以下是案例代码:

import requests
from bs4 import BeautifulSoup
import time
# 请求网页
def page_request(url, ua):
    response = requests.get(url=url, headers=ua)
    html = response.content.decode('utf-8')
    return html
# 解析网页
def page_parse(html):
    soup = BeautifulSoup(html, 'lxml')
    # 获取每部电影的排名
    position = soup.select('#content > div > div.article > ol > li > div > div.pic > em')
    # 获取豆瓣电影名称
    name = soup.select('#content > div > div.article > ol > li > div > div.info > div.hd > a > span:nth-child(1)')
    # 获取电影评分
    rating = soup.select('#content > div > div.article > ol > li> div > div.info > div.bd > div > span.rating_num')
    # 获取电影链接
    href = soup.select('#content > div > div.article > ol > li > div > div.info > div.hd > a')
    for i in range(len(name)):
        print(position[i].get_text()+'\t'+name[i].get_text()+'\t' + rating[i].get_text() + '\t' + href[i].get('href'))

if __name__ == "__main__":
    print('**************开始爬取豆瓣电影**************')
    ua = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4421.5 Safari/537.36'}
    # 豆瓣电影Top250每页有25部电影,start就是每页电影的开头
    for startNum in range(0, 251, 25):
        url = "https://movie.douban.com/top250?start=%d" % startNum
        html = page_request(url=url, ua=ua)
        page_parse(html=html)
        print('**************爬取完成**************')

本案例中使用CSS选择器来获取标签,如何直接在浏览器获取指定元素的CSS选择器:

我们打开网页后,例如要获取《肖申克的救赎》电影的导演,把鼠标移动至该电影的导演处,右击,选择审查元素

b57808d9dc914c3281c051e584dee587.png

在右侧的元素区可以定位到该信息在html网页源码的具体位置

377eaf5a07244afe9975413d5af1f165.png

然后在对应标签处右击,选择复制——复制selector

59bb643dd7984bafabb0ca4032aabb2b.png

将复制好的selector粘贴到soup.select()中即可。

f8e3839c7b984fd7881d6e0ccb41cb40.png

以下为爬取结果:

122132dab9e34e38bb455555616d0ffc.png

二、案例二:访问热搜榜并发送邮件

访问微博热搜榜(https://s.weibo.com/top/summary),获取微博热搜榜前50条热搜名称、链接及其实时热度,并将获取到的数据通过邮件的形式,每20秒发送到个人邮箱中。

本案例需要获取User-Agent、Accept、Accept-Language、Accept-Ecoding、Cookie五个字段,前四个字段可能都是相同的,主要是Cookie不同。

具体获取流程如下:

打开目标网页:https://s.weibo.com/top/summary按键盘上面F12进入开发者模式,再按F5刷新页面,会出现网页相关信息:

63062ab79d3d4e65b29a5e41d2324406.png

依次点击Network、All、以及summary(即目标链接的地址):

7d26cc55d200483da566995889cfe003.png

点击summary后出现右侧窗口,点击Header能够得到相关报文字段。

23b55c637504452c8c39e4fbcc18d978.png

本案例所需的字段均在Request Header中,即下图中标注的字段。具体字段对应的值以各自浏览器为主,无需与图中字段值相同

db0b78ddda8844aa895177c425cc1e0b.png

记住User-Agent、Accept、Accept-Language、Accept-Ecoding、Cookie五个字段值,后续在代码中会用到。

然后再去QQ邮箱获取邮箱的smtp授权码就可以进行爬取操作了,本案例还是使用CSS选择器获取指定元素信息。其中,热搜榜置顶没有显示热度,需要特殊处理。另外就是部分热搜的链接会出现别的情况,也需要特殊处理。

获取发送邮箱的smtp授权码:

smtp授权码只需要发送邮箱的,不是接收邮箱的。因为不是我们自己主动发送邮件,通过第三方(python代码)发送的,所以需要获取smtp授权码进行第三方登录。本案例以QQ邮箱为例,获取QQ邮箱的smtp授权码,其他类型邮箱类似或者可以上网查找相关资料。

打开QQ邮箱设置-账户,往下滑找到如图所示的选项:

3b81234356cd43ccbdbbe5722895d8f2.png

2ca1f21910cb42af804e783542893735.png

将以上4个服务都开起来,然后点击管理服务,点生成授权码

2812a49982c94ec68060021427569533.png

这样授权码就生成了

e231cf0eb26340c4bad9854d8f1acd8c.png

以下是本案例代码,把User-Agent、Accept、Accept-Language、Accept-Ecoding、Cookie五个字段值改成刚刚在网页中查询到的,然后发送邮箱、邮箱授权码、接收邮箱也填写自己对应的信息

# 爬虫相关模块
import requests
from bs4 import BeautifulSoup

# 发送邮箱相关模块
import smtplib
from email.mime.text import MIMEText
from email.header import Header
# 定时模块
import schedule
import time
# 请求网页
def page_request(url, header):
    response = requests.get(url=url, headers=header)
    html = response.content.decode("UTF-8")
    return html
# 解析网页
def page_parse(html):
    soup = BeautifulSoup(html, 'lxml')
    news = []
    # 处理热搜前50
    urls_title = soup.select('#pl_top_realtimehot > table > tbody > tr > td.td-02 > a')
    hotness = soup.select('#pl_top_realtimehot > table > tbody > tr > td.td-02 > span')
    for i in range(len(urls_title)):
        new = {}
        title = urls_title[i].get_text()
        url = urls_title[i].get('href')
        # 个别链接会出现异常
        if url == 'javascript:void(0);':
            url = urls_title[i].get('href_to')
        # 热搜top没有显示热度
        if i == 0:
            hot = 'top'
        else:
            hot = hotness[i - 1].get_text()

        new['title'] = title
        new['url'] = "https://s.weibo.com" + url
        new['hot'] = hot
        news.append(new)
    print(len(news))
    for element in news:
        print(element['title'] + '\t' + element['hot'] + '\t' + element['url'])
    # 发送邮件
    sendMail(news)

# 将获取到的热搜信息发送到邮箱
def sendMail(news):
    # 发送邮箱
    from_addr = '123456789@qq.com'
    # 发送邮箱授权码,不是邮箱密码,而是smtp授权码
    password = 'qwertyuiopasdfghj'
    # 接收邮箱
    to_addr = '123456789@qq.com' #同发送邮箱一致即可
    # qq邮箱的smtp地址
    maihost = 'smtp.qq.com'
    # 建立SMTP对象
    qqmail = smtplib.SMTP()
    # 25为SMTP常用端口
    qqmail.connect(maihost, 25)
    # 登录邮箱
    qqmail.login(from_addr, password)
    # 设置发送邮件的内容
    content = ''
    for i in range(len(news)):
        content += str(i) + '、\t' + news[i]['title'] + '\t' + '热度:' + news[i]['hot'] + '\t' + '链接:' + news[i][
            'url'] + ' \n'

    get_time = time.strftime('%Y-%m-%d %X', time.localtime(time.time())) + '\n'
    content += '获取事件时间为' + get_time

    # 设置邮件的格式以及发送主题
    msg = MIMEText(content, 'plain', 'utf-8')
    msg['subject'] = Header('微博热搜', 'utf-8')

    try:
        qqmail.sendmail(from_addr, to_addr, msg.as_string())
        print('succeed sending')
    except:
        print('fail sending')
    qqmail.quit()


def job():
    print('**************开始爬取微博热搜**************')
    header = {
        #这里需要把刚刚在网页中查到的5个字段值复制过来
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
        'Accept-Encoding': 'gzip, deflate, br',
        'Cookie':'SINAGLOBAL=8549294076109.952.1627630535328; SCF=AmIX2oJN4JoxCFYkUXJ8d5QQyBZHO1JXA83iG2eNq4IscDqAUCUDp5f88UyhJ4JyEKtT4Yo3dq7Vn83aUhIgZjA.; ALF=1708263527; SUB=_2A25Irgs3DeRhGeVG7VIU8CfLyDyIHXVrwgL_rDV8PUJbkNB-LXTTkW1NT4u8pivIKQtIDTnD-jhxDtabI8u60fQ2; SUBP=0033WrSXqPxfM725Ws9jqgMF55529P9D9WW-cOiz3beFWXRE5_p11MAN5JpX5KMhUgL.FoeRSo5feh.Ne052dJLoIEBLxKML1h2LBo5LxKML1K.LB.BLxKMLBK.LB.2LxKMLBK.LB.2t; _s_tentry=-; Apache=481270234981.17926.1705671528382; ULV=1705671528401:3:1:1:481270234981.17926.1705671528382:1702348377653'
    }

    url = 'https://s.weibo.com/top/summary'
    html = page_request(url=url, header=header)
    page_parse(html)

if __name__ == "__main__":
# 定时爬取,每隔20s爬取一次微博热搜榜并将爬取结果发送至个人邮箱
# 可以将20修改成其他时间
    schedule.every(20).seconds.do(job)
    while True:
        schedule.run_pending()

运行结果

c07fde8493c745eab511f54f30da10ad.png

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值