博客列表 >利用Python获取某游戏网站热销商品并用pands进行Excel数据存储

利用Python获取某游戏网站热销商品并用pands进行Excel数据存储

IPIDEA全球HTTP
IPIDEA全球HTTP原创
2022年10月10日 14:24:08547浏览

由于审核原因,本文中的网站以S代替。

有刚刚使用S的用户,不知道玩什么游戏怎么办?往往热销商品会使他们最合适的选择。

当然,某个第三方的网站上面的数据会更详细,什么游戏用户活跃度高,哪个区服游戏价格更便宜上面都会有。但是加上了一层Cloudflare的浏览器验证。

有人说用cloudscraper,但是cloudscraper对商用版的Cloudflare好像不管用(应该是吧,如果有大佬有更好的方法请及时指出,谢谢),之后会用其他的方法再试试。所以这边先按下不表,开始获取S的热销信息。

 

一、热销获取分析

点击进入热销商品页:

https://那个网站/search/?sort_by=_ASC&force_infinite=1&snr=1_7_7_globaltopsellers_7&filter=globaltopsellers&page=2&os=win

上面的链接,仅仅能获取第一页的数据。

通过开发者模式找到真正的内容获取链接是:

https://那个网站/search/results/?query&start=0&count=50&sort_by=_ASC&os=win&snr=1_7_7_globaltopsellers_7&filter=globaltopsellers&infinite=1

其中start对应了开始位置,对应了翻页。count对应了一次获取了多少数据。

get请求即可,上代码:

def getInfo(self):  
2.        url = 'https://那个网站/search/results/?query&start=0&count=50&sort_by=_ASC&os=win&snr=1_7_7_globaltopsellers_7&filter=globaltopsellers&infinite=1'  
3.        res = self.getRes(url,self.headers,'','','GET')#自己封装的请求方法  
4.        res = res.json()['results_html']  
5.        sel = Selector(text=res)  
6.        nodes = sel.css('.search_result_row')  
7.        for node in nodes:  
8.            gamedata = {}  
9.            gamedata['url'] = node.css('a::attr(href)').extract_first()#链接  
10.            gamedata['name'] = node.css('a .search_name .title::text').extract_first()#游戏名  
11.            gamedata['sales_date'] = node.css('a .search_released::text').extract_first()#发售日  
12.            discount = node.css('.search_discount span::text').extract_first()#是否打折  
13.            gamedata['discount'] = discount if discount else 'no discount'  
14.            price = node.css('a .search_price::text').extract_first().strip()#价格  
15.            discountPrice = node.css('.discounted::text').extract()#打折后的价格  
16.            discountPrice = discountPrice[-1] if discountPrice else ''  
17.            gamedata['price'] = discountPrice if discountPrice else price#最终价格  
18.            print(gamedata)

 1665382379519090.png

二、pandas保存数据 

2.1 构建pandas DataFrame对象

pandas存储Excel数据利用的是pandas对象的to_excel方法,将pandas的Dataframe对象直接插入Excel表中。

而DataFrame表示的是矩阵的数据表,包含已排序的列集合。

首先,先将获取到的数据,构建成Dataframe对象,先将我们获取的数据分别存入对应的list中,获取的url存到url的list,游戏名存到name的list:

1. url = []  
2. name = []  
3. sales_date = []  
4. discount = []  
5. price = []

 

1. url = node.css('a::attr(href)').extract_first()  
2. if url not in self.url:  
3.     self.url.append(url)  
4.     name = node.css('a .search_name .title::text').extract_first()  
5.     sales_date = node.css('a .search_released::text').extract_first()  
6.     discount = node.css('.search_discount span::text').extract_first()  
7.     discount = discount if discount else 'no discount'  
8.     price = node.css('a .search_price::text').extract_first().strip()  
9.     discountPrice = node.css('.discounted::text').extract()  
10.     discountPrice = discountPrice[-1] if discountPrice else ''  
11.     price = discountPrice if discountPrice else price  
12.     self.name.append(name)  
13.     self.sales_date.append(sales_date)  
14.     self.discount.append(discount)  
15.     self.price.append(price)  
16. else:  
17.     print('已存在')

将list组成相应的字典

1. data = {  
2.             'URL':self.url,'游戏名':self.name,'发售日':self.sales_date,'是否打折':self.discount,'价格':self.price  
3.         }  
其中dict中的key值对应的是Excel的列名。之后用pandas的DataFrame()方法构建对象,之后插入Excel文件。
1. data = {  
2.             'URL':self.url,'游戏名':self.name,'发售日':self.sales_date,'是否打折':self.discount,'价格':self.price  
3.         }  
4. frame = pd.DataFrame(data)  
5. xlsxFrame = pd.read_excel('./steam.xlsx')

其中pd是引入pandas包的对象,约定俗成的见到pd就是引入了pandas。

import pandas as pd

2.2 pandas追加插入Excel

如果要是翻页的话,重复调用插入Excel方法时你会发现Excel表内的数据并不会增多,因为每一次to_excel()方法都会把你上一次写入的数据覆盖掉。

所以若想保留之前写入的数据,那就先把之前写入的数据读出来,然后和新产生的数据进行DaraFrame对象的合并,将总的数据再次写入Excel

frame = frame.append(xlsxFrame)

 写入方法如下:

1. def insert_info(self):  
2.     data = {  
3.         'URL':self.url,'游戏名':self.name,'发售日':self.sales_date,'是否打折':self.discount,'价格':self.price  
4.     }  
5.     frame = pd.DataFrame(data)  
6.     xlsxFrame = pd.read_excel('./steam.xlsx')  
7.     print(xlsxFrame)  
8.     if xlsxFrame is not None:  
9.         print('追加')  
10.         frame = frame.append(xlsxFrame)  
11.         frame.to_excel('./steam.xlsx', index=False)  
12.     else:  
13.         frame.to_excel('./steam.xlsx', index=False)

逻辑:

1.将已有的数据生成DataFrame

2.读取之前写入的Excel文件,判断是否写入过数据

3.如果写入,将数据读出来合并后再次写入Excel

4.如果源文件为空,直接写入即可

三、代码整合

1. import requests  
2. from scrapy import Selector  
3. import pandas as pd  
4.    
5. class getSteamInfo():  
6.    
7.     headers = {  
8.         "Host": "那个网站",  
9.         "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",  
10.         "accept-encoding": "gzip, deflate, br",  
11.         "accept-language": "zh-CN,zh;q=0.9",  
12.         "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36",  
13.     }  
14.    
15.     url = []  
16.     name = []  
17.     sales_date = []  
18.     discount = []  
19.     price = []  
20.    
21.     # api获取ip  
22.     def getApiIp(self):  
23.         # 获取且仅获取一个ip  
24.         api_url = 'api地址'  
25.         res = requests.get(api_url, timeout=5)  
26.         try:  
27.             if res.status_code == 200:  
28.                 api_data = res.json()['data'][0]  
29.                 proxies = {  
30.                     'http': 'http://{}:{}'.format(api_data['ip'], api_data['port']),  
31.                     'https': 'http://{}:{}'.format(api_data['ip'], api_data['port']),  
32.                 }  
33.                 print(proxies)  
34.                 return proxies  
35.             else:  
36.                 print('获取失败')  
37.         except:  
38.             print('获取失败')  
39.    
40.     def getInfo(self):  
41.         url = 'https://那个网站/search/results/?query&start=0&count=50&sort_by=_ASC&os=win&snr=1_7_7_globaltopsellers_7&filter=globaltopsellers&infinite=1'  
42.         res = self.getRes(url,self.headers,'','','GET')#自己封装的请求方法  
43.         res = res.json()['results_html']  
44.         sel = Selector(text=res)  
45.         nodes = sel.css('.search_result_row')  
46.         for node in nodes:  
47.             url = node.css('a::attr(href)').extract_first()  
48.             if url not in self.url:  
49.                 self.url.append(url)  
50.                 name = node.css('a .search_name .title::text').extract_first()  
51.                 sales_date = node.css('a .search_released::text').extract_first()  
52.                 discount = node.css('.search_discount span::text').extract_first()  
53.                 discount = discount if discount else 'no discount'  
54.                 price = node.css('a .search_price::text').extract_first().strip()  
55.                 discountPrice = node.css('.discounted::text').extract()  
56.                 discountPrice = discountPrice[-1] if discountPrice else ''  
57.                 price = discountPrice if discountPrice else price  
58.                 self.name.append(name)  
59.                 self.sales_date.append(sales_date)  
60.                 self.discount.append(discount)  
61.                 self.price.append(price)  
62.             else:  
63.                 print('已存在')  
64.         # self.insert_info()  
65.    
66.     def insert_info(self):  
67.         data = {  
68.             'URL':self.url,'游戏名':self.name,'发售日':self.sales_date,'是否打折':self.discount,'价格':self.price  
69.         }  
70.         frame = pd.DataFrame(data)  
71.         xlsxFrame = pd.read_excel('./steam.xlsx')  
72.         print(xlsxFrame)  
73.         if xlsxFrame is not None:  
74.             print('追加')  
75.             frame = frame.append(xlsxFrame)  
76.             frame.to_excel('./steam.xlsx', index=False)  
77.         else:  
78.             frame.to_excel('./steam.xlsx', index=False)  
79.    
80.     # 专门发送请求的方法,代理请求三次,三次失败返回错误  
81.     def getRes(self,url, headers, proxies, post_data, method):  
82.         if proxies:  
83.             for i in range(3):  
84.                 try:  
85.                     # 传代理的post请求  
86.                     if method == 'POST':  
87.                         res = requests.post(url, headers=headers, data=post_data, proxies=proxies)  
88.                     # 传代理的get请求  
89.                     else:  
90.                         res = requests.get(url, headers=headers, proxies=proxies)  
91.                     if res:  
92.                         return res  
93.                 except:  
94.                     print(f'第{i+1}次请求出错')  
95.                 else:  
96.                     return None  
97.         else:  
98.             for i in range(3):  
99.                 proxies = self.getApiIp()  
100.                 try:  
101.                     # 请求代理的post请求  
102.                     if method == 'POST':  
103.                         res = requests.post(url, headers=headers, data=post_data, proxies=proxies)  
104.                     # 请求代理的get请求  
105.                     else:  
106.                         res = requests.get(url, headers=headers, proxies=proxies)  
107.                     if res:  
108.                         return res  
109.                 except:  
110.                     print(f"第{i+1}次请求出错")  
111.                 else:  
112.                     return None  
113.    
114. if __name__ == '__main__':  
115.     getSteamInfo().getInfo()

对了,本次数据是获取的美服数据哦。最近国内访问不稳定,若是想要获取数据不买游戏的话建议使用代理进行访问。我这里使用的是ipidea的代理,新用户可以白嫖流量哦。

地址:http://www.ipidea.net/

最后奉劝大家:适当游戏,理智消费 ,认真生活,支持正版。(大批量的数据还是存数据库吧,人家也支持导出Excel)

 


上一条:简单小后台下一条:课程表模板
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议