用户登录
用户注册

分享至

Python实习之爬虫模板

  • 作者: 我想听她的演唱会
  • 来源: 51数据库
  • 2022-05-09

Python爬虫结构

写爬虫一共需要写这几个函数:

函数 功能
get_resource() 获取网页解析网页
parse_html() 用Xpath或者BS4筛选网页,返回资源列表
downland() 根据上面返回的列表下载资源
main() 函数的入口调用上面函数

函数目录(点击可定位)

get_resourse()函数
parse_html()函数
downland()函数
main()函数
全部代码实现
我们以爬取豆瓣影评为例子:庆余年-豆瓣影评

get_resourse()函数

user_agents = [
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko",
    "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
    "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)",
    "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)",
    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
    "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
    "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11",
]
def get_resource(url, params=None, flag='html'):
    headers = {
        'Host': 'movie.douban.com',
        'User-Agent': random.choice(user_agents)
    }
    # 使用requests发出请求
    response = requests.get(url=url, params=params, headers=headers)
    # 判断response的状态码
    if response.status_code == 200:
        # 判断flag
        if flag == 'html':
            return response.text
        elif flag == 'media':
            return response.content
    else:
        print('获取资源有误!')

说明:这个get_resourse()函数形式固定可以直接ctrl+c,ctrl+v
你需要修改的是上面headers里面的host,这个自己F12吧,然后点击network,筛选doc,自己找吧!!
注意!!
这里面flag='html’时候可以下载文本文件
flag="media"时候下载媒体文件(图片,音频,视频等)
parse_html()函数:

def parse_html(resource):
    comment_list = []
    soup = BeautifulSoup(resource, 'lxml')
    comments = soup.select_one('#comments')
    comment_items = comments.select('.comment-item')
    for item in comment_items:
        comment_info = item.select_one('.comment h3 .comment-info')
        # 用户的头像
        image = item.select_one('.avatar a img').get('src')
        # 评价的用户名
        username = comment_info.find('a').text
        # 获取星级
        star = comment_info.find('span', class_='rating')
        # 有个人他没有星级评论,这里
        if star:
            star = star.get('title')
        else:
        	# 如果这个家伙没有评论,就默认5星吧->力荐
            star = '力荐'
        # 评论内容
        comment_text = item.find('span', attrs={'class': 'short'}).text
        # 保存在一个列表中
        comment = [username, star, image, comment_text]
        # 将其添加到列表中
        comment_list.append(comment)

    return comment_list

说明这个要自己筛选/解析html网页,找到要爬取的网页按下F12分析,筛选出自己想要的标签。用Xpath或者BeautifulSoup命令
忘记的小伙伴点击这里:
Xpath:Xpath教程 CQG
BS4:BeautifulSoup教程 CQG

我建议大家学BS4,这个我比较擅长,我觉得好用

基本思路:
筛选你想要的东西然后以列表形式储存起来,然后遍历每个项,分别取用评论、星级、用户名。然后用列表储存起来,返回这个带有评论、星级、用户名的列表
下一步就轮到我们的downland()函数出场了

downland()函数

def downland(comment_list):
    # 文件操作:这是你返回的列表  [[],[],[],[],[]]
    # a 是追加模式,不然覆盖的话就剩下最后一页的了
    with open('data/douban.csv', mode='a', newline='', encoding='utf-8') as fw:
        writer = csv.writer(fw)
        # 遍历评论列表
        writer.writerows(comment_list)

    print('保存完毕!')

我们下载列表成csv文件
忘记CSV文件操作的小伙伴点击这里:CSV储存格式-CQG
如果你要下载图片、视频等媒体文件,这就比较复杂
因为它是媒体文件,我们get_resourse()函数的flag要传入
flag=‘media’,不再是默认的flag='html’了
下面给出下载图片的代码片段
一定要弄清楚如何下载媒体文件(图片,视频)
一定要理解flag="media"就是那个get_resourse()

downland_img(courses)
  #返回的course列表 course=[['/files/course....','xxxx'],[],[],...]
  #每个列表项:['/files/course....','xxxx']
  #每个列表项:['图片路径','文字']
  #python可以这样分别循环 图片、文字
  #image循环列表项第一个路径
  #title循环列表项第二个路径
  #这么写
  for image, title in courses:
        url = 'http://www.51sjk.com/Upload/Articles/1/0/310/310612_20210801001103031.com' + image
        # 借助requests完成图片的获取
        # 你现在回过头看我们写的getresourse函数
        # 里面有两个1.flag=html, 2.flag=media
        # 我们要下载媒体文件(图片,视频)需要用flag="media"获取网页
        content = get_resourse(url, flag='media')
        # 这个是用后面做文件名
        filename = url.rsplit('/')[-1]  # ['http://www.51sjk.com/Upload/Articles/1/0/310/310612_20210801001103031.com/files/course/2019/03-05','170936087d5a394261.jpg']
        print(filename)
        # 保存
        # 保存到本地媒体资源用[二进制写入]
        # mode="wb"
        with open('images/' + filename, mode='wb') as fw:
            fw.write(content)
        print('成功下载:', filename)

注意:downland()函数可能要写多个,比如你下载歌词乐曲歌手专辑封面图片要分开下载
你就需要写很多downland():
downland_music()
downland_
main()函数
main函数灵活调用上面三个函数

if __name__ == '__main__':
    url = 'http://www.51sjk.com/Upload/Articles/1/0/310/310612_20210801001103156.jpg'
    # 这些是网页url参数,我们切换页面时?后面的东西
    params = {'status': 'P', 'limit': 20, 'sort': 'new_score'}
    # 这是爬取多页评论用的
    # 我们观察到每翻页一次params中的start就增长20
    # 由于点击下一页,其实就是参数变化
    for i in range(10):
        n = i * 20
        params['start'] = n
        # 调用函数获取资源
        # 每一页由于参数变化,就是不同链接
        # 每一页爬取都要请求整个网页
        resource = get_resource(url=url, params=params,flag='html')
        # print(resource)
        # 调用解析方法:bs4  获取所有的评论内容,并返回list内容
        # 用BS4筛选
        comment_list = parse_html(resource)
        # 保存
        downland(comment_list)
        # 延时
        time.sleep(5)
        print('成功下载第{}页评论....'.format(i + 1))

说明:main函数就是调用上面的get_resourse()parse_html(),downland()
全部代码实现:
爬取庆余年豆瓣影评

# 评论信息爬取
# 豆瓣
import csv
import random
import re
import time

import requests
from bs4 import BeautifulSoup
from lxml import etree

user_agents = [
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko",
    "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
    "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)",
    "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)",
    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
    "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
    "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11",
]


# 1。获取html
def get_resource(url, params=None, flag='html'):
    headers = {
        'Host': 'movie.douban.com',
        'User-Agent': random.choice(user_agents)
    }
    # 使用requests发出请求
    response = requests.get(url=url, params=params, headers=headers)
    # 判断response的状态码
    if response.status_code == 200:
        # 判断flag
        if flag == 'html':
            return response.text
        elif flag == 'media':
            return response.content
    else:
        print('获取资源有误!')


# 2. 解析网页内容
# 采用方式:beautifulSoup4
def parse_html(resource):
    comment_list = []
    soup = BeautifulSoup(resource, 'lxml')
    comments = soup.select_one('#comments')
    comment_items = comments.select('.comment-item')
    for item in comment_items:
        comment_info = item.select_one('.comment h3 .comment-info')
        # 用户的头像
        image = item.select_one('.avatar a img').get('src')
        # 评价的用户名
        username = comment_info.find('a').text
        # 获取星级
        star = comment_info.find('span', class_='rating')
        # 有个人他没有星级评论,这里
        if star:
            star = star.get('title')
        else:
        	# 如果这个家伙没有评论,就默认5星吧->力荐
            star = '力荐'
        # 评论内容
        comment_text = item.find('span', attrs={'class': 'short'}).text
        # 保存在一个列表中
        comment = [username, star, image, comment_text]
        # 将其添加到列表中
        comment_list.append(comment)

    return comment_list

# 3. 封装:持久化保存(保存数据)
def downland(comment_list):
    # 文件操作:csv   [[],[],[],[],[]]
    # a 是追加模式,不然覆盖的话就剩下最后一页的了
    with open('data/douban.csv', mode='a', newline='', encoding='utf-8') as fw:
        writer = csv.writer(fw)
        # 遍历评论列表
        writer.writerows(comment_list)

    print('保存完毕!')

# 只在本类下调用运行,其他类导入的话程序不会运行
if __name__ == '__main__':
    url = 'http://www.51sjk.com/Upload/Articles/1/0/310/310612_20210801001103156.jpg'
    params = {'status': 'P', 'limit': 20, 'sort': 'new_score'}
    for i in range(10):
        n = i * 20
        params['start'] = n
        # 调用函数获取资源
        resource = get_resource(url=url, params=params)
        # print(resource)
        # 调用解析方法:bs4  获取所有的评论内容,并返回list内容
        comment_list = parse_html(resource)
        # 保存
        downland(comment_list)
        # 延时
        time.sleep(5)
        print('成功下载第{}页评论....'.format(i + 1))

软件
前端设计
程序设计
Java相关