基础爬虫实战案例之获取游戏商品数据

2023-05-16

文章目录

  • 前言
  • 一、爬虫是什么?
  • 二、爬虫实战案例
    • 1.引入库
    • 2.请求网页处理
    • 3.生成访问链接
    • 4.读入数据到mongodb
    • 5.获得数据
    • 6.加入多线程
  • 总结


前言

在想获取网站的一些数据时,能过人工手动复制和粘贴,这样的效是不非常低的,数量少的时候可能觉得什么事,当数量多起来的时候就会显得很无力,因此爬虫就被按排上场了,本文就介绍了爬虫学习的基础内容。


一、爬虫是什么?

网络爬虫,又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者,是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本,另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

二、爬虫实战案例

1.引入库

先入引一些接下来要用的库
代码如下(示例):

# requests 用来爬取页面
import requests
# logging 用来输出信息
import logging
# re 用来实现正则表达式解析
import re
# pymongo 用来链接mongodb数据库的
import pymongo
# 随机
import random
from lxml import etree
# urljoin 用来做 URL 的拼接
from urllib.parse import urljoin
# 多线程的引入
import multiprocessing
# pymongo有自带的连接池和自动重连机制,但是仍需要捕捉AutoReconnect异常并重新发起请求。
from pymongo.errors import AutoReconnect
from retry import retry
# 随机获取 UserAgent
from fake_useragent import UserAgent
import time

2.请求网页处理

scrape_page 方法是模仿浏览器发送请求用判断请求网页是否成功,以及出现异常的处理
代码如下(示例):

# 开始时间
start = time.time()

'''
如果没有为根日志程序定义处理程序,debug()、info()、warning()、error()和 critical() 函数将自动调用 basicConfig()。

level	将根记录器级别设置为指定的级别。默认生成的 root logger 的 level 是 logging.WARNING,低于该级别的就不输出了。级别排序:CRITICAL > ERROR > WARNING > INFO > DEBUG。(如果需要显示所有级别的内容,可将 level=logging.NOTSET)

format	为处理程序使用指定的格式字符串。
指定输出格式
'''
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s - %(levelname)s: %(message)s')

# 写入请求头
headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'zh-CN,zh;q=0.9',
    'cache-control': 'max-age=0',
    'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="99", "Google Chrome";v="99"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'User-Agent': UserAgent().chrome
}

# 代理IP列表
Proxies = [
    {"http": "http://3.221.105.1:80"},
    {"http": "http://3.221.105.1:80"},
    {"http": "http://3.221.105.1:80"},
]

def scrape_page(url):

    logging.info('scraping %s (···)', url)
    try:
        # 向url对应的服务器发送相应的get请求,获得对应的相应 。
        response = requests.get(
            url, proxies=random.choice(Proxies), headers=headers)
        # 如果响应码为200则返回网页源码
        if response.status_code == 200:
            return response.text
        # 如果不是200就在日志里打印出响应码和链接
        logging.error('get invalid status code %s while scraping %s',
                      response.status_code, url)
        # requests 的异常处理
    except requests.RequestException:
        # exc_info为布尔值,如果该参数的值为True时,则会将异常信息添加到日志消息中;如果没有则会将None添加到日志信息中。
        logging.error('error occurred while scraping %s', url, exc_info=True)

3.生成访问链接

scrape_index 方法是将生成的 url 全写入生成器中便于下次二次使用
代码如下(示例):

# 要爬取的网站链接
TSY_URL = 'https://www.taoshouyou.com/game/zhaohuanyingxiong-24798-0-3'

GAME_NAME = '召唤英雄'
# 初始化需要爬取的总页码数量
TOTAL_PAGE = 1

def scrape_index(url):
    html = scrape_page(url)
    # 获取页码数
    pattern = r'<li><a>(.*?)</a></li>'
    TOTAL_PAGE = re.findall(pattern, html, re.S)[0]
    TOTAL_PAGE = TOTAL_PAGE.split('/')[1]

    # 生成链接列表
    for page in range(1, int(TOTAL_PAGE) + 1):
        # 拼接url
        game_url = url + '/0-0-0-0-0-1-0-0-0-' + str(page) + '?quotaid=0'
        yield game_url

4.读入数据到mongodb

将爬取到的数据写入到mongodb数据库中
代码如下(示例):


# 指定 mongodb 的连接IP,库名,集合
MONGO_CONNECTION_STRING = 'mongodb://192.168.27.101:27017'
MONGO_DB_NAME = 'tsy'
MONGO_COLLECTION_NAME = 'tsy'

client = pymongo.MongoClient(MONGO_CONNECTION_STRING)
db = client['tsy']
collection = db['tsy']

'''
AutoReconnect:捕捉到该错误时进行重试,这个参数可以是一个元组,里面放上多个需要重试的条件
tries:重试次数
delay:两次重试的间隔时间
'''
@retry(AutoReconnect, tries=4, delay=1)
def save_data(data):
    """
    将数据保存到 mongodb
    使用 update_one() 方法修改文档中的记录。该方法第一个参数为查询的条件,第二个参数为要修改的字段。
    upsert:
    是一种特殊的更新,如果没有找到符合条件的更新条件的文档,就会以这个条件和更新文档为基础创建一个新的文档;如果找到了匹配的文档,就正常更新,upsert非常方便,不必预置集合,同一套代码既能用于创建文档又可以更新文档
    """
    # 存在则更新,不存在则新建,
    collection.update_one({
        # 保证 标题链接数据 是唯一的
        '标题链接': data.get('标题链接')
    }, {
        '$set': data
    }, upsert=True)

5.获得数据

获取数据并且对数据进行简单的处理
代码如下(示例):

def parse_detail(url):
    html = scrape_page(url)
    # 格式化html
    selector = etree.HTML(html)
    house_list = selector.xpath(
        '//*[@id="js-b-trade-list-conlist-trade-list"]/div[@class="row b-trade-list-conlist-box"]')
    # 历遍每一条数据
    for house in house_list:
        biaoti = house.xpath("h1/a/span/text()")
        if len(biaoti) >= 1:
            biaoti = biaoti[0]
            zhekou = house.xpath("h1/a/span[2]/text()")
            jiage = re.findall(r'(\d+\.\d{2})', biaoti.strip())
            dianpu = house.xpath('div[1]/dl/dd[1]/span[2]/a/text()')
            shangpinleixing = house.xpath('div[1]/dl/dd[2]/text()')
            kehuduan = house.xpath('div[1]/dl/dd[3]/text()')
            youxiqufu = house.xpath('div[1]/dl/dd[4]/span/text()')
            html_1 = house.xpath('h1/a/@href')
            if zhekou == [] or dianpu == [] or shangpinleixing == [] or kehuduan == [0] or youxiqufu == [0]:
                print("这不是我需要的")
            else:

                zhekou = re.findall(r'\d+\.?\d*', zhekou[0])
                game_date = {
                    '标题': biaoti.strip(),
                    '折扣': zhekou[0],
                    '价格': jiage[0][:-3],
                    '店铺': dianpu[0],
                    '商品类型': shangpinleixing[0].split(':')[1],
                    '客户端类型': kehuduan[0].split(':')[1],
                    '游戏区服': youxiqufu[0],
                    # 拼接url
                    '标题链接': urljoin('https://www.taoshouyou.com', html_1[0]),
                    '游戏名': GAME_NAME
                }
                logging.info('get detail data %s', game_date)
                logging.info('saving data to mongodb')
                save_data(game_date)
                logging.info('data saved successfully')

6.加入多线程

代码如下(示例):

if __name__ == '__main__':
    # 引入多线程
    pool = multiprocessing.Pool()
    detail_urls = scrape_index(TSY_URL)
    # map()函数。需要传递两个参数,第一个参数就是需要引用的函数,第二个参数是一个可迭代对象,它会把需要迭代的元素一个个的传入第一个参数我们的函数中。因为我们的map会自动将数据作为参数传进去

    # 传入一个url列表,parse_detail方法每次只能获取一条url
    pool.map(parse_detail, detail_urls)
    # 关闭mongodb连接
    client.close()

    # 关闭进程池,不再接受新的进程
    pool.close()
    # 主进程阻塞等待子进程的退出
    pool.join()

    # 结束时间
    end = time.time()
    print('Cost time: ', end - start)

总结

以上就是今天要讲的内容,本文仅仅简单介绍了针对网页源码中有数据可获取的爬虫使用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基础爬虫实战案例之获取游戏商品数据 的相关文章

随机推荐

  • lua元表、元方法

    lua元表 元方法 lua官方参考手册 xff1a https www runoob com manual lua53doc manual html 2 4 一 总结 xff1a 1 普通的表 xff0c 找不到了 xff0c 或者无法进行
  • 一个less文件中引入另一个less文件

    假设有两个 less的文件1 less 和2 less 在1 less 中引入2 less文件 64 import 34 2 less 34 34 34 是一定不可以忘记的
  • Python——函数

    函数的创建和调用 xff1a 函数的创建和调用 为什么需要函数 xff1a 复用代码 隐藏实现细节 提高可维护性 提高可读性便于调试 函数的创建 def 函数名 输入参数 函数体 return xxx span class token ke
  • ubuntu18.04安装微信

    1 安装deepin wine 使用shell的方法下载各种deb包 1 具体的操作为 xff1a 在home中打开终端 xff08 terminal xff09 xff0c 运行以下语句 xff1a gedit install sh 弹出
  • 实现MySql的主从复制(两台虚拟机)详解

    实现MySql的主从复制 xff08 非单机 xff09 文章目录 实现MySql的主从复制 xff08 非单机 xff09 首先了解心跳线实现数据同步一 mysql主从复制原理是什么 xff1f 二 使用步骤1 安装Mysql2 数据库进
  • ubuntu安装完anaconda,添加快捷启动方式

    1 进入文件夹 xff0c 找到anaconda的bin文件并进入 home 用户 anaconda3 bin 2 进入后右键打开terminal 3 在terminal中输入 anaconda navigator 4 这时候就会发现ana
  • 分别用汇编语言、C语言编程实现LED流水灯

    一 C语言编程 1 先创建一个新的工程 2 文件名 3 右键Source Group创建一个 c文件 4 在 c文件中放入以下代码 APB2使能时钟寄存器 define RCC AP2ENR unsigned volatile int 0x
  • SyntaxError: invalid syntax的问题原因和解决办法

    写在这里的初衷 xff0c 一是备忘 xff0c 二是希望得到高人指点 xff0c 三是希望能遇到志同道合的朋友 目录 一 问题二 原因及解决办法 一 问题 span class token comment An highlighted b
  • Java 字符串匹配的三种方法

    文章目录 一 示例二 解释1 replace 方法2 replaceAll 方法3 replaceFirst 方法4 常用的字符列表 一 示例 如图 xff0c 都是为了替换字符串s中的 34 34 符号 xff0c 但三种匹配方法 xff
  • 【VMware+ubuntu】关闭还原虚拟机后网络断开的解决办法

    使用ifconfig和ip addr 发现对应网卡down掉了 手动执行ifcconfig ens33 up把网卡up起来 xff0c 发现网卡是起来了 xff0c 但是没有IP 重启网络服务sudo service network man
  • MySQL中的视图

    视图概述 视图是一种虚拟存在的表 xff0c 并不在数据库中实际存在 xff0c 它的数据依赖于真实存在的数据表 通过视图不仅可以看到其依赖数据表中的数据 xff0c 还可以像操作数据表一样 xff0c 对数据表中的数据进行添加 修改和删除
  • ubuntu在更新软件时出现E: Release file for http://security.ubuntu.com/ubuntu/dists/bionic-security/InRelease

    问题 E Release file for http security ubuntu com ubuntu dists bionic security InRelease is not valid yet invalid for anoth
  • 配置pip环境变量以及PYTHONPATH的作用

    配置pip环境变量 python的环境变量PYTHONPATH PYTHONPATH是Python搜索路径 xff0c 默认我们import的模块都会从PYTHONPATH里面寻找
  • AtCoder Beginner Contest 218 C - Shapes (模拟)

    linkkkk 题意 xff1a 给两个 n n n n n n 的矩阵 xff0c
  • CF1169C. Increasing by Modulo(二分)

    linkkkkk 题意 xff1a 给出 n k n k n k 和数组 a a
  • 【c++类的构造函数】几种写法及问题

    c 43 43 类的构造函数 几种写法及问题 一 构造函数的定义 类通过一个或几个特殊的与类同名的成员函数来控制其对象的初始化过程 xff0c 这些函数叫构造函数 构造函数的任务是初始化类对象的数据成员 xff0c 无论何时只要类的对象被创
  • 【洛谷】P1786 帮贡排序 2020-11-07

    洛谷 P1786 帮贡排序 简单结构体排序题 xff0c 用bool函数加sort就可以 主要的点是如果需要按某种奇怪的顺序排序的话 xff0c 就把那个奇怪的顺序表上号好了 题解 xff1a xff08 还是多加注释比较好 xff09 s
  • 链表:头插法与尾插法(简易图解和代码)

    头插法 定义 xff1a 输入的数据次序生成的链表节点次序相反 xff0c 例如 xff1a 按1 2 3顺序进行头插之后 xff0c 最终排序却变成了3 2 1 简而言之就是逆序插入 定义图解 xff1a 代码图解 xff1a 代码 xf
  • Robomaster基于传统算法的视觉识别教程

    文章目录 前言一 装甲板的分析二 预处理降低曝光度ROI区域 三 颜色提取提取目标颜色阈值化与膨胀 四 灯条轮廓提取五 灯柱筛选六 灯柱匹配其他总结 前言 本文记载个人在RM视觉组中学习到的传统算法和opencv用法及代码实例讲解 xff0
  • 基础爬虫实战案例之获取游戏商品数据

    文章目录 前言一 爬虫是什么 xff1f 二 爬虫实战案例1 引入库2 请求网页处理3 生成访问链接4 读入数据到mongodb5 获得数据6 加入多线程 总结 前言 在想获取网站的一些数据时 xff0c 能过人工手动复制和粘贴 xff0c