欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Python实习之爬虫模板

程序员文章站 2022-04-16 08:17:19
Python爬虫结构写爬虫一共需要写这几个函数:函数功能get_resource()获取网页解析网页parse_html()用Xpath或者BS4筛选网页,返回资源列表downland()根据上面返回的列表下载资源main()函数的入口调用上面函数函数目录(点击可定位)get_resourse()函数parse_html()函数downland()函数main()函数全部代码实现我们以爬取豆瓣影评为例子:庆余年-豆瓣影评get_resou...

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命令
忘记的小伙伴点击这里:
XpathXpath教程 CQG
BS4BeautifulSoup教程 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.codingke.com' + image
        # 借助requests完成图片的获取
        # 你现在回过头看我们写的getresourse函数
        # 里面有两个1.flag=html, 2.flag=media
        # 我们要下载媒体文件(图片,视频)需要用flag="media"获取网页
        content = get_resourse(url, flag='media')
        # 这个是用后面做文件名
        filename = url.rsplit('/')[-1]  # ['http://www.codingke.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 = 'https://movie.douban.com/subject/25853071/comments'
    # 这些是网页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 = 'https://movie.douban.com/subject/25853071/comments'
    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))

本文地址:https://blog.csdn.net/chengqige/article/details/107335403