自己也打csgo,就想着抓个全站数据用于可视化和预测分析,直接开始撸。

本篇文章将带你从抓包分析到分析数据加载方式以及网页结构分析再到代码实现爬虫获取数据。

本篇文章使用到redis,mysql以及scrapy框架,部分知识自行学习。

1. 对网站结构进行分析,了解数据的加载方式,并爬取起始页面的饰品信息

CS:GO饰品市场_网易BUFF饰品交易平台进入首页,针对饰品分类进行分析。先进入匕首分类,打开控制台抓包对关键字进行搜索,搜索7120饰品的价格。

可以看到饰品的信息和价格都是通过https://buff.163.com/api/market/goods?这个api接口加载返还前端页面,咱们这里只用用xpath解析前端页面是无法拿到数据的,切换到其他分类查看接口参数规律,关键参数game=csgo 游戏类型,page_num=1 页数, category_group=knife这个是我们的分类,在前端页面可以抓取到各个分类的名称

分析到这咱们已经可以拿到分类标题,分类的链接已经饰品的属性等数据,直接老套路,新建一个scrapy项目

输入 scrapy startproject Buff

切换到Buff目录下

输入 scrapy genspider arms https://buff.163.com/market/csgo

这样一个项目就创建完成了

打开我们的spider文件,正常输入上面两串代码后会生成如下文件,打开我们的arms

初始项目一般都只有这几行代码,name是我们定义的爬虫名称, allowed_domains是域名,start_urls为起始的url,创建好项目后我们首先应该检查的是域名和起始的url是否和网站上的一致,如果不一致自行修改。

接着开始写代码了,我们明确我们需要抓取的数据:分类名称,分类页的url。打开我们的items.py文件,对所需要抓取的数据进行建模。

# -- items.py --
import scrapyclass BuffItem(scrapy.Item):biglabel = scrapy.Field()biglabel_link = scrapy.Field()

来到我们的arms.py文件中,scrapy默认的提取数据方式有xpath和css,这里我们使用到xpath提取我们所需要的分类名称,然后对分类页的url进行一个拼接,分类页中的url有时间戳,并不知道服务器会不会对此进行验证,所以我们还是都带上。

# -- arms.py --
import scrapy
import timeclass ArmsSpider(scrapy.Spider):name = 'arms'allowed_domains = ['buff.163.com']start_urls = ['https://buff.163.com/market/csgo']def parse(self, response):node_list = response.xpath('//*[@class="h1z1-selType type_csgo"]/div')for node in node_list:base_data = {}base_data['biglabel'] = node.xpath('.//p/text()').get()base_data['biglable_link'] = 'https://buff.163.com/api/market/goods?game=csgo&page_num=1&category_group={}&use_suggestion=0&trigger=undefined_trigger&_={}'.format(node.xpath('.//p/@value').get(), int(time.time() * 1000))print(base_data)

完成后运行我们的arms查看base_data是否正确

控制台输入 scrapy crawl arms      # 运行爬虫

第一步就算完成了,我们继续分析第二步详细页面的数据该如何抓取,以及实现翻页操作。

2. 详细页面的数据抓取

解析详细页面的数据,当然就需要对我们刚刚拼接下来的url进行请求,我们重新定义一个函数 parse_img(self, response):  将上一个函数获取的数据通过meta进行传递到parse_img函数中,并且我们需要在parse中加入我们的cookie,需要注意的是,scrapy中的cookies的格式为字典,我们需要对cookies中的每一个字段封装成一个字典。具体操作如下,如果不添加cookies则请求biglabel_link时将无数据返回,同时我们打开setting.py和middlewares.py文件,配置我们的User_Agent,scrapy中默认使用scrapy的ua,很容易被服务器识别出。

# -- arms.py --   def parse(self, response):node_list = response.xpath('//*[@class="h1z1-selType type_csgo"]/div')for node in node_list:base_data = {}base_data['biglabel'] = node.xpath('.//p/text()').get()base_data['value'] = node.xpath('.//p/@value').get()base_data['biglable_link'] = 'https://buff.163.com/api/market/goods?game=csgo&page_num=1&category_group={}&use_suggestion=0&trigger=undefined_trigger&_={}'.format(node.xpath('.//p/@value').get(), int(time.time() * 1000))cookie = '_ntes_nnid=2168b19b62d64bb37f40162a1fd999cf,1656839072318; _ntes_nuid=2168b19b62d64bb37f40162a1fd999cf; Device-Id=zteGfLiffEYmzr7pzqXn; _ga=GA1.2.1822956190.1656920597; vinfo_n_f_l_n3=4f2cffc01c7d98e1.1.0.1657365123345.0.1657365133193; hb_MA-8E16-605C3AFFE11F_source=www.baidu.com; hb_MA-AC55-420C68F83864_source=www.baidu.com; __root_domain_v=.163.com; _qddaz=QD.110858392929324; Locale-Supported=zh-Hans; game=csgo; Hm_lvt_eaa57ca47dacb4ad4f5a257001a3457c=1656920596,1658582225,1658721676; _gid=GA1.2.109923849.1658721677; NTES_YD_SESS=XFu19pwcHN6Blr5FRmVVtMV81vu_q8LPnNvqzF_aBBLVAZ_WA7Kw6g3z0x.OnVZMav2Ct9VuprshE6tCMRo1iMtqZtzZa9kp4Y77cost521PJbbZt_Zw9WtdpVwDUUF4QXKWPYURB6P8PZT97Ar4Rde7Tg2EiB1L5n9lVw.3Z6GrETAU6i5ct03n9LcMEld0JF7Zqj_Gl2wTJGt1fx3tyz8NuI1YoOmb7Oh9VTxwoqYE3; S_INFO=1658722544|0|0&60##|18958675241; P_INFO=18958675241|1658722544|1|netease_buff|00&99|null&null&null#gux&450300#10#0|&0||18958675241; remember_me=U1095406721|LG3tz94sUOGVVIXZQjo8lJ1AwzVQbaMk; session=1-UWdoO73qKkqBcWzo4Cz2l1lZz2HToVVUjAFknHzNIT6n2038696921; _gat_gtag_UA_109989484_1=1; Hm_lpvt_eaa57ca47dacb4ad4f5a257001a3457c=1658722546; csrf_token=ImZjMDM1NzJhOTVmYWI2NGRmMjJkN2I1ZDUzYTBkMGIzZGM4N2ZjOTIi.Fb-qfQ.kliU6aNIb4iHTYaX16iMNAY73VI'cookies = {data.split('=')[0]: data.split('=')[1] for data in cookie.split(';')}yield scrapy.Request(url=base_data['biglable_link'],callback=self.parse_img,meta={'base_data': base_data},cookies=cookies)def parse_img(self, response):temp = response.meta['base_data']

ua配置如下,在setting文件中添加一个USER_AGENT列表,如何在下载器中间件随机选取ua,记得要打开下载器管道。

# -- middlewares.py --
from .settings import USER_AGENT_LIST
import randomclass RandomUserAgent:def process_request(self, request, spider):UserAgent = random.choice(USER_AGENT_LIST)request.headers['User-Agent'] = UserAgent   # 随机替换UA

setting.py中添加

# -- setting.py --
DOWNLOADER_MIDDLEWARES = {'Buff.middlewares.RandomUserAgent': 300,
}USER_AGENT_LIST = ["Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60","Opera/8.0 (Windows NT 5.1; U; en)","Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36","Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11","Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1","Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6","Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6","Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
]ROBOTSTXT_OBEY = False

单独抓一个页面出来请求,用json转格式后发现了个神奇的东西

'total_page': 122      这个东西先记着,之后会用到。

由于我们想要抓取详细数据,api接口所返回的格式为json类型,scrapy默认的xpath和css这时候已经用不上了,我们在arms.py中导入jsonjsonpath这两个包,jsonpath是基于xpath的json格式的数据提取器,所用到的语法都差不多,对于scrapy调试json类型的数据,建议先用requests对单页进行请求,把提取规则写好后再套入scrapy当中。

直接将jsonpath的提取规则套入我们的scrapy当中,对数据进行提取。同时打开我们的items.py文件对这些元素进行建模,建模完成后在arms.py文件中导入我们的items.py Buffitems()这个类,对其进行实例化。

    # -- arms.py --def parse_img(self, response):base_data = response.meta['base_data']json_data = json.loads(response.text)id = jsonpath.jsonpath(json_data, '$..items[*].id')name = jsonpath.jsonpath(json_data, '$..items[*].name')market_name = jsonpath.jsonpath(json_data, '$..items[*].market_hash_name')price = jsonpath.jsonpath(json_data, '$..items[*].sell_min_price')exterior_wear = jsonpath.jsonpath(json_data, '$..info.tags.exterior.localized_name')quality = jsonpath.jsonpath(json_data, '$..info.tags.quality.localized_name')rarity = jsonpath.jsonpath(json_data, '$..info.tags.rarity.localized_name')type = jsonpath.jsonpath(json_data, '$..info.tags.type.localized_name')weapon_type = jsonpath.jsonpath(json_data, '$..info.tags.weapon.localized_name')for i in range(len(id)):item = BuffItem()item['biglabel'] = base_data['biglabel']item['biglabel_link'] = base_data['biglable_link']item['id'] = id[i]item['name'] = name[i]item['market_name'] = market_name[i]item['price'] = price[i]item['exterior_wear'] = exterior_wear[i]item['quality'] = quality[i]item['rarity'] = rarity[i]item['type'] = type[i]item['weapon_type'] = weapon_type[i]yield item

最终运行效果如下

3. 翻页功能实现

在这一步之前,我们所实现的功能只能够爬取一页的内容,这远远达不到我们想要抓取全站数据的目标。在这一步,我们将实现翻页功能,对每一页的数据都进行提取。

还记得我们之前找到的那个 'total_page': 122 ,只要观察就能发现,这个代表着每一个分类一共有多少页面,我们把他提取出来就能够知道最多多少页,并根据这个页数写我们的翻页规则,直接干。

在我们的arms.py文件parse_img这个函数中,写我们的翻页功能,首先提取出页数,非常简单

page = jsonpath.jsonpath(json_data, '$.data.total_page')[0]

写入我们的scrapy当中

# -- arms.py --page = jsonpath.jsonpath(json_data, '$.data.page_num')[0] + 1pages = jsonpath.jsonpath(json_data, '$.data.total_page')[0]if page <= pages:# print(base_data['value'])next_url = 'https://buff.163.com/api/market/goods?game=csgo&page_num={}&category_group={}&use_suggestion=0&trigger=undefined_trigger&_={}'.format(page, base_data['value'], int(time.time() * 1000))cookie = '_ntes_nnid=2168b19b62d64bb37f40162a1fd999cf,1656839072318; _ntes_nuid=2168b19b62d64bb37f40162a1fd999cf; Device-Id=zteGfLiffEYmzr7pzqXn; _ga=GA1.2.1822956190.1656920597; vinfo_n_f_l_n3=4f2cffc01c7d98e1.1.0.1657365123345.0.1657365133193; hb_MA-8E16-605C3AFFE11F_source=www.baidu.com; hb_MA-AC55-420C68F83864_source=www.baidu.com; __root_domain_v=.163.com; _qddaz=QD.110858392929324; Locale-Supported=zh-Hans; game=csgo; Hm_lvt_eaa57ca47dacb4ad4f5a257001a3457c=1656920596,1658582225,1658721676; _gid=GA1.2.109923849.1658721677; NTES_YD_SESS=XFu19pwcHN6Blr5FRmVVtMV81vu_q8LPnNvqzF_aBBLVAZ_WA7Kw6g3z0x.OnVZMav2Ct9VuprshE6tCMRo1iMtqZtzZa9kp4Y77cost521PJbbZt_Zw9WtdpVwDUUF4QXKWPYURB6P8PZT97Ar4Rde7Tg2EiB1L5n9lVw.3Z6GrETAU6i5ct03n9LcMEld0JF7Zqj_Gl2wTJGt1fx3tyz8NuI1YoOmb7Oh9VTxwoqYE3; S_INFO=1658722544|0|0&60##|18958675241; P_INFO=18958675241|1658722544|1|netease_buff|00&99|null&null&null#gux&450300#10#0|&0||18958675241; remember_me=U1095406721|LG3tz94sUOGVVIXZQjo8lJ1AwzVQbaMk; session=1-UWdoO73qKkqBcWzo4Cz2l1lZz2HToVVUjAFknHzNIT6n2038696921; _gat_gtag_UA_109989484_1=1; Hm_lpvt_eaa57ca47dacb4ad4f5a257001a3457c=1658722546; csrf_token=ImZjMDM1NzJhOTVmYWI2NGRmMjJkN2I1ZDUzYTBkMGIzZGM4N2ZjOTIi.Fb-qfQ.kliU6aNIb4iHTYaX16iMNAY73VI'cookies = {data.split('=')[0]: data.split('=')[1] for data in cookie.split(';')}yield scrapy.Request(url=next_url,callback=self.parse_img,meta={'base_data': base_data},cookies=cookies)

定义了page每一次都加1开始,比如现在是第一页所以page=2,假设pages=100,如果page小于且等于pages,则会一直循环下去。

这里有个小插曲,爬的太快了被网站限制,为了和谐相处,咱们打开setting文件设置下载延迟。

在setting.py中添加

DOWNLOAD_DELAY = 3                # 下载延迟
CONCURRENT_REQUESTS = 8        # scrapy最大的并发量,默认为16

在测试过程中,发现频繁报了一个错,bool类型的数据不可下标,进入对于的url查看,发现有些饰品缺少些元素,正常info内会有五个标签

修改我们的arms.py,最终为

import scrapy
import time
import json
import jsonpath
from ..items import BuffItemclass ArmsSpider(scrapy.Spider):name = 'arms'allowed_domains = ['buff.163.com']start_urls = ['https://buff.163.com/market/csgo']def parse(self, response):node_list = response.xpath('//*[@class="h1z1-selType type_csgo"]/div')for node in node_list:base_data = {}base_data['biglabel'] = node.xpath('.//p/text()').get()base_data['value'] = node.xpath('.//p/@value').get()base_data['biglable_link'] = 'https://buff.163.com/api/market/goods?game=csgo&page_num=1&category_group={}&use_suggestion=0&trigger=undefined_trigger&_={}'.format(base_data['value'], int(time.time() * 1000))cookie = '_ntes_nnid=2168b19b62d64bb37f40162a1fd999cf,1656839072318; _ntes_nuid=2168b19b62d64bb37f40162a1fd999cf; Device-Id=zteGfLiffEYmzr7pzqXn; _ga=GA1.2.1822956190.1656920597; vinfo_n_f_l_n3=4f2cffc01c7d98e1.1.0.1657365123345.0.1657365133193; hb_MA-8E16-605C3AFFE11F_source=www.baidu.com; hb_MA-AC55-420C68F83864_source=www.baidu.com; __root_domain_v=.163.com; _qddaz=QD.110858392929324; Locale-Supported=zh-Hans; game=csgo; Hm_lvt_eaa57ca47dacb4ad4f5a257001a3457c=1656920596,1658582225,1658721676; _gid=GA1.2.109923849.1658721677; NTES_YD_SESS=XFu19pwcHN6Blr5FRmVVtMV81vu_q8LPnNvqzF_aBBLVAZ_WA7Kw6g3z0x.OnVZMav2Ct9VuprshE6tCMRo1iMtqZtzZa9kp4Y77cost521PJbbZt_Zw9WtdpVwDUUF4QXKWPYURB6P8PZT97Ar4Rde7Tg2EiB1L5n9lVw.3Z6GrETAU6i5ct03n9LcMEld0JF7Zqj_Gl2wTJGt1fx3tyz8NuI1YoOmb7Oh9VTxwoqYE3; S_INFO=1658722544|0|0&60##|18958675241; P_INFO=18958675241|1658722544|1|netease_buff|00&99|null&null&null#gux&450300#10#0|&0||18958675241; remember_me=U1095406721|LG3tz94sUOGVVIXZQjo8lJ1AwzVQbaMk; session=1-UWdoO73qKkqBcWzo4Cz2l1lZz2HToVVUjAFknHzNIT6n2038696921; _gat_gtag_UA_109989484_1=1; Hm_lpvt_eaa57ca47dacb4ad4f5a257001a3457c=1658722546; csrf_token=ImZjMDM1NzJhOTVmYWI2NGRmMjJkN2I1ZDUzYTBkMGIzZGM4N2ZjOTIi.Fb-qfQ.kliU6aNIb4iHTYaX16iMNAY73VI'cookies = {data.split('=')[0]: data.split('=')[1] for data in cookie.split(';')}yield scrapy.Request(url=base_data['biglable_link'],callback=self.parse_img,meta={'base_data': base_data},cookies=cookies)def parse_img(self, response):base_data = response.meta['base_data']json_data = json.loads(response.text)id = jsonpath.jsonpath(json_data, '$..items[*].id')name = jsonpath.jsonpath(json_data, '$..items[*].name')market_name = jsonpath.jsonpath(json_data, '$..items[*].market_hash_name')price = jsonpath.jsonpath(json_data, '$..items[*].sell_min_price')exterior_wear = jsonpath.jsonpath(json_data, '$..info.tags.exterior.localized_name')quality = jsonpath.jsonpath(json_data, '$..info.tags.quality.localized_name')rarity = jsonpath.jsonpath(json_data, '$..info.tags.rarity.localized_name')type = jsonpath.jsonpath(json_data, '$..info.tags.type.localized_name')weapon_type = jsonpath.jsonpath(json_data, '$..info.tags.weapon.localized_name')for i in range(len(id)):item = BuffItem()item['biglabel'] = base_data['biglabel']item['biglabel_link'] = base_data['biglable_link']item['id'] = id[i]item['name'] = name[i]item['market_name'] = market_name[i]item['price'] = price[i]if not exterior_wear:item['exterior_wear'] = ''else:item['exterior_wear'] = exterior_wear[i]if not quality:item['quality'] = ''else:item['quality'] = quality[i]if not rarity:item['rarity'] = ''else:item['rarity'] = rarity[i]if not type:item['type'] = ''else:item['type'] = type[i]if not weapon_type:item['weapon_type'] = ''else:item['weapon_type'] = weapon_type[i]yield itempage = jsonpath.jsonpath(json_data, '$.data.page_num')[0] + 1pages = jsonpath.jsonpath(json_data, '$.data.total_page')[0]if page <= pages:# print(base_data['value'])next_url = 'https://buff.163.com/api/market/goods?game=csgo&page_num={}&category_group={}&use_suggestion=0&trigger=undefined_trigger&_={}'.format(page, base_data['value'], int(time.time() * 1000))cookie = '_ntes_nnid=2168b19b62d64bb37f40162a1fd999cf,1656839072318; _ntes_nuid=2168b19b62d64bb37f40162a1fd999cf; Device-Id=zteGfLiffEYmzr7pzqXn; _ga=GA1.2.1822956190.1656920597; vinfo_n_f_l_n3=4f2cffc01c7d98e1.1.0.1657365123345.0.1657365133193; hb_MA-8E16-605C3AFFE11F_source=www.baidu.com; hb_MA-AC55-420C68F83864_source=www.baidu.com; __root_domain_v=.163.com; _qddaz=QD.110858392929324; Locale-Supported=zh-Hans; game=csgo; Hm_lvt_eaa57ca47dacb4ad4f5a257001a3457c=1656920596,1658582225,1658721676; _gid=GA1.2.109923849.1658721677; NTES_YD_SESS=XFu19pwcHN6Blr5FRmVVtMV81vu_q8LPnNvqzF_aBBLVAZ_WA7Kw6g3z0x.OnVZMav2Ct9VuprshE6tCMRo1iMtqZtzZa9kp4Y77cost521PJbbZt_Zw9WtdpVwDUUF4QXKWPYURB6P8PZT97Ar4Rde7Tg2EiB1L5n9lVw.3Z6GrETAU6i5ct03n9LcMEld0JF7Zqj_Gl2wTJGt1fx3tyz8NuI1YoOmb7Oh9VTxwoqYE3; S_INFO=1658722544|0|0&60##|18958675241; P_INFO=18958675241|1658722544|1|netease_buff|00&99|null&null&null#gux&450300#10#0|&0||18958675241; remember_me=U1095406721|LG3tz94sUOGVVIXZQjo8lJ1AwzVQbaMk; session=1-UWdoO73qKkqBcWzo4Cz2l1lZz2HToVVUjAFknHzNIT6n2038696921; _gat_gtag_UA_109989484_1=1; Hm_lpvt_eaa57ca47dacb4ad4f5a257001a3457c=1658722546; csrf_token=ImZjMDM1NzJhOTVmYWI2NGRmMjJkN2I1ZDUzYTBkMGIzZGM4N2ZjOTIi.Fb-qfQ.kliU6aNIb4iHTYaX16iMNAY73VI'cookies = {data.split('=')[0]: data.split('=')[1] for data in cookie.split(';')}yield scrapy.Request(url=next_url,callback=self.parse_img,meta={'base_data': base_data},cookies=cookies)

当然这里面还有三级页面,四级页面,进入三级页面能够拿到磨损度的数值以及卖家信息,四级页面能够获取一些卖家的个人信息。网易buff没有任何反爬是我意料之外的,只需要通过登入的滑块就能拿到账号的cookies。

关于更深的爬取我们还可以对三四级页面进行分析,然后使用scrapy-redis进行分布式爬取,加快爬取速度,在时间紧急的情况下推荐用分布式,案例演示我们就只用redis做一个断点续爬就行,咱们直接干。

4. 断点续爬,以及将数据存入mysql当中

断点需怕无谓就是添加几步操作,添加重复过滤模块以及redis的调度器

打开我们的redis,然后在setting.py中添加如下代码。

USER_AGENT = 'scrapy-redis (+https://github.com/rolando/scrapy-redis)'
# 设置重复过滤器的模块
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 设置调度器,scrapy_redis中的调度器具有与数据库交互的功能
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 设置当爬虫结束的时候是否保持redis数据库中的去重集合与任务队列
SCHEDULER_PERSIST = True
ITEM_PIPELINES = {# 'JD.pipelines.ExamplePipeline': 300,# 当开启该管道,该管道会把数据存到redis数据库中'scrapy_redis.pipelines.RedisPipeline': 400,
}REDIS_HOST = 'host'
REDIS_PORT = port
REDIS_ENCODING = 'utf-8'
REDIS_PARAMS = {'password':'your redis password'}

运行后可以看到,数据库中多了两个键,其中dupefilter是我们的url去重指纹,在scrapy中默认url去重为md5加密,加密过后的数值能更节省内存,items为我们的数据

其中增量式爬虫原理也相同:在请求页面前会对数据库内的文件进行匹配,如果指定的元素存在数据库当中,则跳过该链接的请求,去拿没获取过的数据。

如果想对数据进行持久化存储,那就得考虑mysql或者存储为csv文件,这里我们两个都演示。打开我们的pipelines.py文件,编写我们的管道中间件,默认情况下pipelines.py文件如下:

将pipelines.py文件修改如下.

import csv
import pymysqlclass BuffPipeline:def open_spider(self, spider):self.file = open(file='arms.csv', mode='a', encoding='utf-8-sig', newline='')self.csvwriter = csv.writer(self.file)self.csvwriter.writerow(['biglabel', 'biglabel_link', 'id', 'name', 'market_name', 'price', 'exterior_wear', 'quality', 'rarity', 'type', 'weapon_type'])def process_item(self, item, spider):self.csvwriter.writerow([item['biglabel'], item['biglabel_link'], item['id'], item['name'], item['market_name'], item['price'], item['exterior_wear'], item['quality'], item['rarity'], item['type'], item['weapon_type']])return itemdef close_spider(self, spider):self.file.close()class MysqlPipeline:def open_spider(self, spider):self.mysql = pymysql.connect(host='localhost', user='root', password='your mysql password', db='sys', port=3306, charset='utf8')self.cursor = self.mysql.cursor()sql = '''create table buff(biglabel char(255),biglabel_link char(255),id char(255),name char(255),market_name varchar(500),price char(30),exterior_wear char(255),quality varchar(255),rarity char(255),type char(255),weapon_type char(255))'''self.cursor.execute(sql)    # 创建表格def process_item(self, item, spider):insert_sql = '''insert into buff(biglabel, biglabel_link, id, name, market_name, price, exterior_wear, quality, rarity, type, weapon_type) value ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')''' % (item['biglabel'], item['biglabel_link'], item['id'], item['name'], item['market_name'], item['price'], item['exterior_wear'], item['quality'], item['rarity'], item['type'], item['weapon_type'])self.cursor.execute(insert_sql)self.mysql.commit()   # 提交return item# 关闭def close_spider(self, spider):self.cursor.close()self.mysql.close()

记住要提前打开我们的mysql和redis,然后在setiing中设置我们的管道和redis一页,最后实现的效果如下。

好了,就这么多。

某Buff CSGO饰品信息获取相关推荐

  1. python爬虫实战-网易BUFF CSGO饰品

    python爬虫实战-网易BUFF CSGO饰品 寒假迷上了csgo,一方面对这个纯粹的枪战游戏着迷,另一方面对精美的饰品着迷.众所周知,csgo是个理财游戏饰品游戏,能够掌握到喜欢饰品的价格就可以得 ...

  2. 爬取网易buff CSGO饰品数据 - 优化篇

    文章目录 思路回顾 配置优化 RawConfigParser 处理配置列表 价格取舍 价格过滤 饰品类别限定 内部实现优化:结合价格筛选和饰品类别筛选 其他限定? 命名 The End 继上周末搞了c ...

  3. 爬取网易buff CSGO饰品数据

    文章目录 需要的东西 API 获取所有饰品 获取每一个类别的饰品 获取所有饰品的steam售价 总结一下 模拟登录 防止ip被封 其他问题 价格区间限制 平均售价 多次爬取 冷门饰品过滤 关于stea ...

  4. 优化某buff csgo饰品

    scrapy获取网易buff饰品信息继上一次的版本,继续优化. 在后期的测试当中,发现无法实现断点续爬的功能,观察发现和我们自己设置的url有关系(自己挖的坑自己跳),具体部分的代码如下,arms.p ...

  5. java爬取验证码图片_JAVA HttpClient实现页面信息抓取(获取图片验证码并传入cookie实现信息获取)...

    JAVA HttpClient实现页面信息抓取(获取图片验证码并传入cookie实现信息获取) 发布时间:2018-05-18 16:41, 浏览次数:632 , 标签: JAVA HttpClien ...

  6. python模块os测试文件是否存在及基础原信息获取

    python模块os测试文件是否存在及基础原信息获取 在自动化测试中,经常需要查找操作文件,比如说查找配置文件(从而读取配置文件的信息),查找测试报告(从而发送测试报告邮件),经常要对大量文件和大量路 ...

  7. Metasploit AFP信息获取模块afp_server_info

    Metasploit AFP信息获取模块afp_server_info AFP服务默认端口为548或者427.通过扫描该端口信息,afp_server_info模块可以获取AFP服务相关信息.这些信息 ...

  8. 【Android工具】更新安卓手机传感器信息获取工具Ampere Castro phyphox,轻松获取硬件数据和状态信息...

    微信关注 "DLGG创客DIY" 设为"星标",重磅干货,第一时间送达. 上次分享过一个安卓手机传感器信息获取工具--Castro(本文下边),这个软件没有充电 ...

  9. windows主机网络信息获取程序设计

    掌握windows系统获取网络信息的各种API函数的功能与调用方法,掌握设计程序显示获取到相关网络信息的方法,掌握网络字节数据与主机字节数据之间的转换.掌握这些API函数调用的错误处理方法. 利用本地 ...

最新文章

  1. Zookeeper整理(一)- 写操作产生事件,写操作与Watcher对应关系
  2. 第 5 章 Stream
  3. 3、将对象存储到zookeeper中,然后再拿下来还原
  4. Winform开发框架之混合型框架的实现
  5. 帧同步_帧同步和状态同步该怎么选(上)
  6. shell判断字符串是否为数字
  7. 大文件上传组件集成说明
  8. openfire spark用户名问题续
  9. java整型_java整型数值
  10. SQL教程及学习 我选择了《SQL必知必会》
  11. 台电p10hd拆解_台电X19HD玩家拆机报告
  12. 物业为什么要用微小区SaaS系统进行管理
  13. python猴子偷桃问题_java猴子偷桃问题
  14. 紫罗兰计算机音乐,【Animenz】紫罗兰永恒花园ed みちしるべ
  15. Git提交前端代码遇到Lint errors found in the listed files.和husky - pre-push hook failed (add --no-verify)
  16. 淘宝客小程序制作(4)-小程序(微信支付宝)
  17. 一文搞懂0.1UF和10UF电容并联使用技巧
  18. 【经验】代码统计工具cloc
  19. 投资理财-朋友榕的经历
  20. CVPR2020无人驾驶论文摘要

热门文章

  1. 关于测试工程师的职业发展思考
  2. keras中的卷积层池化层
  3. 深度挖掘:FIashGet下载隐藏链接[转]
  4. Excel解析与数据生成(撑持JXL,POI)
  5. 发芽大蒜竟有意想不到的神奇功效
  6. 高压之下依然能高效发挥才是真本事
  7. ORACLE 中OVER()结合rank(),dense_rank(),rownumber() 使用方法
  8. 【转载】传统蓝牙协议栈 串口协议SPP
  9. 企业微信内容如何值入广告?
  10. 在 4GB 物理内存的机器上,申请 8G 内存会怎么样?