提示:本作品为原创,转载请经过作者同意


前言

随着乌克兰和俄罗斯局势变换,俄罗斯的著名游戏网站BYRUTOR解封,在咱们欣欣然去下载游戏时发现,网站自带的检索系统竟然只支持英文,这非常的不方便,于是我就想,能不能给他做一个中文检索系统,输入中文便能弹到对应的游戏窗口呢?


一、第一步

代码

先上代码:

import re  # 正则表达式,进行文字匹配`
import xlwt  # 进行excel操作
import requests
from multiprocessing.dummy import Pool
work_book = xlwt.Workbook(encoding='utf-8')

sheet = work_book.add_sheet('sheet1 ')
sheet.write(0, 0, '游戏链接')
sheet.write(0, 5, '图片链接')
# sheet.write(0,2,'发行年份')
sheet.write(0, 10, '游戏名')
sheet.write(0, 13, '发行年份')
# sheet.write(0,0,'第一行第一列')
# heet.write(0,1,'第一行第二列')
work_book.save('misaka.xls')
byrut = []
for i in range(2,1000,1):
    byrut.append(i)
def out1():
    url = 'https://byrut.org'
    response = requests.get(url=url, headers=headers)
    findLink = re.compile(r'<a href="(.*?).html">')  # 链接
    findImgSrc = re.compile(r'<img src="(.*?)"', re.S)  # 图片链接
    findJudge = re.compile(r'<span>(.*) г.</span>')  # 年份
    findTitle = re.compile(r'<a href=".*">(.*)</a>')  # 名字

    a = findLink.findall(response.text)
    b = findImgSrc.findall(response.text)
    c = findJudge.findall(response.text)
    d = findTitle.findall(response.text)

    for i, j in zip(range(1, 50, 2), range(1, 25)):
        x=a
        sheet.write(j, 0, x[i] + ".html")
        #print(x[i],j)

    for i in range(1, 25, 1):
        x=b
        sheet.write(i, 5, x[i])
        #print(x[i],i)

    for i, j in zip(range(0, 24, 1), range(1, 25)):
        x=c
        # sheet.write(j,2,c)
        m = 0
        n = x[i]
        if n == "":
            continue
        #print(n, j)
        sheet.write(j, 13, n)

    for i, j in zip(range(83, 131, 2), range(1, 25)):
        x=d
        sheet.write(j, 10, x[i])
        #print(x[i])

    print("第1页打印成功!")
    work_book.save('misaka.xls')
def out2(q):
    url = 'https://byrut.org/page/' + str(q) + '/'
    response = requests.get(url=url, headers=headers)
    # print("第"+(str)(q-1)+"页打印成功!")
    m = 0
    findLink = re.compile(r'<a href="(.*?).html">')  # 链接
    findImgSrc = re.compile(r'<img src="(.*?)"', re.S)  # 图片链接
    findJudge = re.compile(r'<span>(.*)</span>')  # 年份
    findTitle = re.compile(r'<a href=".*">(.*)</a>')  # 名字

    a = findLink.findall(response.text)
    b = findImgSrc.findall(response.text)
    c = findJudge.findall(response.text)
    d = findTitle.findall(response.text)


    for i, j in zip(range(1, 50, 2), range(1 * q + 24 * (q - 1), 25 * q)):
        x=a
        sheet.write(j - q + 1, 0, x[i] + ".html")
        #print(a)


    for i, j in zip(range(1, 25, 1), range(1 * q + 24 * (q - 1), 25 * q)):
        x=b
        sheet.write(j - q + 1, 5, x[i])
        #print(b)


    for i, j in zip(range(6, 30, 1), range(1 * q + 24 * (q - 1), 25 * q)):
        x=c
        m = 0
        n = x[i]
        if n == "":
            continue
        #print(n)
        sheet.write(j - q + 1, 13, n)
    # print(q)
    for i, j in zip(range(32, 80, 2), range(1 * q + 24 * (q - 1), 25 * q)):
        x=d
        sheet.write(j - q + 1, 10, x[i])
        #print(d)
    print("第" + (str)(q) + "页打印成功!")
    work_book.save('misaka.xls')
headers = {
            'cookie': 'PHPSESSID=dcccb073e5484add991f356a8d933553; _ga=GA1.1.441223190.1652872369; cf_chl_2=a3d1b21b9bf84d8; cf_chl_prog=x13; cf_clearance=IZu.M8M2nC._6dC3eqWM_E8OwXcPwdo8ySG2B6UQR9o-1654660236-0-150; __cf_bm=AQM.QWE6wAfNpnbYq3I_.VSZcfekrv5H2impMviRMQY-1654660238-0-AQddU/98slJqZdixp/3MtxLFkLm0zDzWZVv67fx6Nfc7OyiS0yUpwjTR74HEnK2GLYhBgGvy3YzsVDqQ4K7sEab4r9lBXglrs8E+S5mpH9Fwhz7YjLHUKwBJjdrtLGTVXg==; _ga_QX7E7T8PJ1=GS1.1.1654658046.10.1.1654660306.0',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.2242 SLBChan/105'
        }


out1()
pool = Pool(6)
pool.map(out2,byrut)
pool.close()
pool.join()
print("打印完成")

代码详解

1.引入库

import re  # 正则表达式,进行文字匹配`
import xlwt  # 进行excel操作
import requests
from multiprocessing.dummy import Pool

2.接收想爬取的网站

 url = 'https://byrut.org'
 url = 'https://byrut.org/page/' + str(q) + '/'

该网站为静态网站,根据观察,换页数只需在https://byrut.org后加/page/加页数

3.获取想爬游戏的信息

    response = requests.get(url=url, headers=headers)
    # print("第"+(str)(q-1)+"页打印成功!")
    m = 0
    findLink = re.compile(r'<a href="(.*?).html">')  # 链接
    findImgSrc = re.compile(r'<img src="(.*?)"', re.S)  # 图片链接
    findJudge = re.compile(r'<span>(.*)</span>')  # 年份
    findTitle = re.compile(r'<a href=".*">(.*)</a>')  # 名字

    a = findLink.findall(response.text)
    b = findImgSrc.findall(response.text)
    c = findJudge.findall(response.text)
    d = findTitle.findall(response.text)


    for i, j in zip(range(1, 50, 2), range(1 * q + 24 * (q - 1), 25 * q)):
        x=a
        sheet.write(j - q + 1, 0, x[i] + ".html")
        #print(a)


    for i, j in zip(range(1, 25, 1), range(1 * q + 24 * (q - 1), 25 * q)):
        x=b
        sheet.write(j - q + 1, 5, x[i])
        #print(b)


    for i, j in zip(range(6, 30, 1), range(1 * q + 24 * (q - 1), 25 * q)):
        x=c
        m = 0
        n = x[i]
        if n == "":
            continue
        #print(n)
        sheet.write(j - q + 1, 13, n)
    # print(q)
    for i, j in zip(range(32, 80, 2), range(1 * q + 24 * (q - 1), 25 * q)):
        x=d
        sheet.write(j - q + 1, 10, x[i])

4.使用正则表达式进行匹配

以上代码为正则表达式匹配链接,图片链接,年份,游戏名称。再以for遍历将数据存储到excel中。关于为什么存储到excel中,有两个好处,这里先卖个关子,后面慢慢讲。

注:爬取年份时,网站个别游戏并未写出年份,这会导致正则表达式报错,使用if-continue解决。

5.解决反爬问题

headers = {
            'cookie': 'PHPSESSID=dcccb073e5484add991f356a8d933553; _ga=GA1.1.441223190.1652872369; cf_chl_2=a3d1b21b9bf84d8; cf_chl_prog=x13; cf_clearance=IZu.M8M2nC._6dC3eqWM_E8OwXcPwdo8ySG2B6UQR9o-1654660236-0-150; __cf_bm=AQM.QWE6wAfNpnbYq3I_.VSZcfekrv5H2impMviRMQY-1654660238-0-AQddU/98slJqZdixp/3MtxLFkLm0zDzWZVv67fx6Nfc7OyiS0yUpwjTR74HEnK2GLYhBgGvy3YzsVDqQ4K7sEab4r9lBXglrs8E+S5mpH9Fwhz7YjLHUKwBJjdrtLGTVXg==; _ga_QX7E7T8PJ1=GS1.1.1654658046.10.1.1654660306.0',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.2242 SLBChan/105'
        }

byrut = []
for i in range(2,1000,1):
	byrut.append(i)
pool = Pool(6)
pool.map(out2,byrut)
pool.close()
pool.join()   

不愧是毛子的网站,反爬做的是真的真的好,普通用户登录会有防机器人验证,像是这样:
在这里插入图片描述
普通的反爬破解手段根本不起作用,当然高大上的反爬太费劲了,咱们就学一学毛子:暴力破解!!!
已知User-Agent + cookie可以破解绝大部分的反爬,它可以让我们的爬虫伪装成一个人畜无害的浏览器发起访问,但是!!!毛子的网站设置了定时检测,意思就是说每隔一段时间我们的cookie就会失效,会返回403。而且它的有效时间特别短,怎么办呢,既然说是暴力,那就在这有限的时间里把所有想要的数据爬取下来不就完了。而实现这一点就需要------多线程进行。

6.爬虫多线程

byrut = []
for i in range(2,1000,1):
	byrut.append(i)
pool = Pool(6)
pool.map(out2,byrut)
pool.close()
pool.join()   

这里使用了线程池,具体原理这里不讲了,直接将应用:

byrut = []
for i in range(2,1000,1):
	byrut.append(i) 

咱们要爬1000页的数据,就先准备一个从2到1000的列表做为线程的参数(第一页单独运行)

pool = Pool(6)

创建一个线程池,里面有6个线程,不需要太多,一是占用内存,二是调用线程需要时间,太多反而会慢

pool.map(out2,byrut)
pool.close()
pool.join()

第一行传入两个参数,第一个是函数,可以接受一个参数,第二个是一个列表,里面存着想要传入第一个函数的参数,然后根据线程数量,编译器会自动分配。
第三第四行结束进程,防止出现僵尸进程。

7.运行程序

先用电脑登录网页,通过机器人验证,然后迅速复制cookie到headers里面
在做好准备工作后,终于可以用python获取数据了
在这里插入图片描述

在这里插入图片描述
成功!!!

二、第二步


别急,爬取成功只是我们计划中的第一步,咱们运行完会得到一个名叫misak的excel,想要检索到想玩的游戏还得去百度游戏对应的英文名用excel检索,这样未免太麻烦了,还不如直接用网站自带的检索系统,创建一个中文检索程序成了我们要思考的问题。

寻找中文英文之间的联系


说到这个,大家肯定会想到翻译软件,谷歌呀百度翻译可以实现,但是很遗憾,因为游戏起名字有点唯心,大部分的翻译不说不对吧,只能说是牛头不对马嘴
在这里插入图片描述
这是只狼2的翻译结果
在这里插入图片描述
这是戴森球计划的翻译
这翻译结果给中国人看能猜出游戏名的估计…emm,我猜没有
所以只能转换思路,咱们一般还能在哪里获取游戏名称呢?没错,各个百科,以百度百科为例,我惊奇的发现对网址进行小幅度修改后,搜索网址是有规律可循的:
在这里插入图片描述
在这里插入图片描述
注意网址,https://baike.baidu.com/item/+中文名即可,而百科中有游戏的中英文名,再使用爬虫获取英文名然后匹配打开对应的网址就可以实现中文检索!
实践开始

代码

# -*- codeing = utf-8 -*-
from bs4 import BeautifulSoup  # 网页解析,获取数据
import re  # 正则表达式,进行文字匹配`
import urllib.request, urllib.error  # 制定URL,获取网页数据
import xlwt  # 进行excel操作
import requests
import random
import matplotlib.pylab as plt
import numpy as np
import pandas as pd
import matplotlib.pyplot as plot
import sys
import webbrowser
flag = 0
B=[0]*1300
C=[0]*1300
print("输入游戏名称:",end='')
dato = 'https://baike.baidu.com/item/'
x=input()
url = dato+x
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.2242 SLBChan/105'
}
response = requests.get(url,headers=headers)
findLink = re.compile(r'<dd class="basicInfo-item value">([\s\S]*?)</dd>')
a = findLink.findall(response.text)[1]
l=len(a)
a=a.replace("\n","")
l=len(a)
if(l>=20):
    for i in range(0,l,1):
        if(a[i]=='<'):
            oo=i
            a=a[0:oo]
            break
df = pd.read_excel("C:\\Users\\86177\\OneDrive\\桌面\\第二次大作业\\auto.xls")
B = df['游戏名']
C = df['游戏链接']
y = len(C)
for j in range(0,y,1):
    if(a.lower()==B[j].lower()):
        b = C[j]
        flag = 1
        break
    
if(flag == 0):
    print("没有此游戏")
else:
    sys.path.append("libs")
    url=b
    webbrowser.open(url)
    print(webbrowser.get())

代码详解

1.读取excel

df = pd.read_excel("misaka.xls")
B = df['游戏名']
C = df['游戏链接'] 

2.输入想找的游戏名并爬取它对应的英文

print("输入游戏名称:",end='')
dato = 'https://baike.baidu.com/item/'
x=input()
url = dato+x
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.2242 SLBChan/105'
}
response = requests.get(url,headers=headers)
findLink = re.compile(r'<dd class="basicInfo-item value">([\s\S]*?)</dd>')
a = findLink.findall(response.text)[1]
l=len(a)
a=a.replace("\n","")
l=len(a)
if(l>=20):
    for i in range(0,l,1):
        if(a[i]=='<'):
            oo=i
            a=a[0:oo]
            break

3.爬取的英文与excel中的游戏名进行匹配

for j in range(0,y,1):
    if(a.lower()==B[j].lower()):
        b = C[j]
        flag = 1
        break
if(flag == 0):
    print("没有此游戏")
else:
    sys.path.append("libs")
    url=b
    webbrowser.open(url)
    print(webbrowser.get())

4.若搜寻到了则打开游戏网页

    sys.path.append("libs")
    url=b
    webbrowser.open(url)
    print(webbrowser.get())

完成!!!
最后再打包一下,以后想下载游戏再也不用费劲的去找游戏英文名再检索啦
运行结果:
在这里插入图片描述
在这里插入图片描述
完美!!!

总结

这次使用了两次爬虫和excel操作,中间有许多细节需要注意,尤其是线程池,注意不要出现僵尸进程,希望能方便到大家,谢谢!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐