丨游戏灬需要 发表于 2020-10-9 18:55:07

关于selenium的

怎么向建立出的浏览器发送ctrl+t(或者直接建立新的窗口啊?)

不能是用下面的方法:
from selenium import webdriver
browser =webdriver.Firefox()
browser.execute_script(f'window.open("{url}")')

这方法没办法建新超过21个窗口

suchocolate 发表于 2020-10-9 18:55:08

本帖最后由 suchocolate 于 2020-10-9 20:01 编辑

丨游戏灬需要 发表于 2020-10-9 19:35
我想着用selenium代替requests爬取网页信息 .例如爬取英雄联盟所有角色的所有皮肤(对,我就是如此的渣渣 ...


import requests


def main():
    headers = {'user-agent': 'firefox'}
    for hero in range(1, 877):
      # 英雄数据的url是固定的,从1-876
      url = f'https://game.gtimg.cn/images/lol/act/img/js/hero/{hero}.js'
      r = requests.get(url, headers=headers)
      # 数据都在这里,具体想用那个自己选,这里只是打印供你参考。
      result = r.json()['skins']
      for item in result:
            print(item)
            print('-' * 100)


if __name__ == '__main__':
    main()

suchocolate 发表于 2020-10-9 19:00:23

本帖最后由 suchocolate 于 2020-10-9 19:03 编辑

这就是新建选项卡的方法。
要那么多选项卡做啥?多进程?

丨游戏灬需要 发表于 2020-10-9 19:09:31

本帖最后由 丨游戏灬需要 于 2020-10-9 19:13 编辑

suchocolate 发表于 2020-10-9 19:00
这就是新建选项卡的方法。
要那么多选项卡做啥?多进程?

想一次开打100个以上的网页(目标是无限多个) ,然后统一操作.可惜这方法最多打开20个
或者有没有办法用execute_script这个方法发送'ctrl+t'的js命令?

suchocolate 发表于 2020-10-9 19:19:45

丨游戏灬需要 发表于 2020-10-9 19:09
想一次开打100个以上的网页(目标是无限多个) ,然后统一操作.可惜这方法最多打开20个
或者有没有办法用 ...

估计selenium性能没有那么强,ctrl-t就是浏览器开选项卡,是一回事。
要不你发下你想操作的网站,以及想操作啥,说说,看看能不能用其他模块实现。

丨游戏灬需要 发表于 2020-10-9 19:35:52

本帖最后由 丨游戏灬需要 于 2020-10-9 19:37 编辑

suchocolate 发表于 2020-10-9 19:19
估计selenium性能没有那么强,ctrl-t就是浏览器开选项卡,是一回事。
要不你发下你想操作的网站,以及 ...

我想着用selenium代替requests爬取网页信息 .例如爬取英雄联盟所有角色的所有皮肤(对,我就是如此的渣渣 ,还在拿这种题练手).
requests爬取时 ,页面有可能没加载完或者爬取后的信息不完整(浏览器f12里面有的 ,响应回的html信息里没有),例如用requests爬https://lol.qq.com/data/info-defail.shtml?id=1时 ,css选择器里都找不到'#skinNAV > li'这复制出来的信息(试过 ,但不知道还是不是一样).
还有皮肤图片信息 ,它需要点击页面里那些小头像后才会加载 ,这个requests也是爬不到(例如要爬原图 ,需要你点击小头像后才会加载 ,还是一个一个加载的(在f12的网络那),所以不可能用requests一个一个爬那些图片吧) .所以
所以想着是不是selenium比requests更通用些

如果真没有的话 ,那么大概暂时只能每20个20个来爬了

丨游戏灬需要 发表于 2020-10-9 20:11:53

本帖最后由 丨游戏灬需要 于 2020-10-9 20:24 编辑

suchocolate 发表于 2020-10-9 19:56


这个确实可以 ,不过 ,你那url是怎么获得?
还有个问题就是残月之肃id=523 ,而下一个角色血港鬼影派克的id=555 ,也就是说 ,它不一定是按这么个顺序排的(所以用最简单的try:except?解决).
而且最后一个角色的id=876 ,每次更新都会增加 ,而增加的是什么数我们也不可能知道

所以我想着的是先从最基础的页面获取所有id组成的列表 ,然后再根据id进入单个角色的界面 ,然后爬取单个角色的所有皮肤信息那些(以此循环全部角色)

suchocolate 发表于 2020-10-9 20:17:35

丨游戏灬需要 发表于 2020-10-9 20:11
这个确实可以 ,不过 ,你那url是怎么获得?

f12-网络-xhr,这种是ajax。
图片总归有来源,要么html里,要么json里,直接放javascript里很少见,安全高的需要配合javascript解密得到。
lol这个看f12就知道规律了。
1.js这个url从登陆的id=1的页面得来,2.js也是从id=2的得来,以此类推。

丨游戏灬需要 发表于 2020-10-9 20:38:19

suchocolate 发表于 2020-10-9 20:17
f12-网络-xhr,这种是ajax。
图片总归有来源,要么html里,要么json里,直接放javascript里很少见,安全 ...

ok吧.url找到是找到了.但是这种全部信息刚好有的js字典 ,还是不太放心,怕其他网页找不到(例如得像点击小头像才能加载大图的情况) .ok先这样吧

丨游戏灬需要 发表于 2020-10-9 21:19:50

suchocolate 发表于 2020-10-9 20:17
f12-网络-xhr,这种是ajax。
图片总归有来源,要么html里,要么json里,直接放javascript里很少见,安全 ...

大佬留步 ,还是不太行啊 .例如你的那个方法(应该是教学机构教的标准方法(嫖的体验课上看过)) ,
首先 ,你可以看看https://game.gtimg.cn/images/lol/act/img/js/hero/876.js ,里面有一堆空信息 ,而实际爬的时候只需要两个皮肤信息而已.
其次 ,爬王者荣耀皮肤好像却不行 ,因为我打开https://pvp.qq.com/web201605/herodetail/533.shtml 页面时 ,没看到有一样的js ,而用html爬取也爬取不到(就是我所说的那种情况 f12里有 ,但res里没有(soup里找到后却不是))

suchocolate 发表于 2020-10-10 18:01:30

本帖最后由 suchocolate 于 2020-10-10 19:13 编辑

丨游戏灬需要 发表于 2020-10-9 21:19
大佬留步 ,还是不太行啊 .例如你的那个方法(应该是教学机构教的标准方法(嫖的体验课上看过)) ,
首先 ,你 ...

只是帮你打印一下整体信息,用什么你自己选,比如只要iconImg;print(item['iconImg'])。
爬虫就是这样,定制化很强,往往不通用,即使用爬虫架构,不同的网站,甚至有时不同的页面都需要定制不同的代码。
掌握方法,自己分析写代码。

suchocolate 发表于 2020-10-10 19:13:53


import requests
import re
import os
from lxml import etree


def ck_dir():
    pic_dir = 'pics'
    if not os.path.exists(pic_dir):
      os.mkdir(pic_dir)
    os.chdir(pic_dir)


def main():
    ck_dir()
    headers = {'user-agent': 'firefox'}
    count = 1
    port_url = 'https://pvp.qq.com/web201605/herolist.shtml'
    r = requests.get(port_url, headers=headers)
    r.encoding = 'gbk'
    html = etree.HTML(r.text)
    # 获取英雄主页列表
    li_list = html.xpath('//ul/li')
    # 遍历列表
    for li in li_list:
      # 获取英雄主页资源url
      h_url = li.xpath('./a/@href')
      # 合成访问url
      port_url = f'https://pvp.qq.com/web201605/{h_url}'
      r = requests.get(port_url, headers=headers)
      # 获取图片base 路径
      p_url = re.findall(r'(game.*?bigskin-)1.jpg', r.text)
      # 统计皮肤数目,url数据等于pic数
      p_num = len(re.findall(r'pf_pic.jpg', r.text))
      # 下载所有皮肤
      for jtem in range(1, p_num + 1):
            # 用base路径+数目合成图片url
            url = f'https://{p_url}{jtem}.jpg'
            # print(url)
            # 取名
            p_name = url.split('/')[-1]
            r = requests.get(url, headers=headers, timeout=5)
            with open(p_name, 'wb') as f:
                f.write(r.content)
            print(f'已下载{p_name},共下载{count}张图片。')
            count = count + 1


if __name__ == '__main__':
    main()

丨游戏灬需要 发表于 2020-10-10 21:21:45

suchocolate 发表于 2020-10-10 19:13


class WZskin():
    def __init__(self):
      self.Did_LskinId_skinNameLD ={}
      pass
    def get_all_id(self):
      url =r'https://pvp.qq.com/web201605/js/herolist.json'
      response =requests.get(url)
      response.encoding =response.apparent_encoding
      for i in response.json():
            id =i['ename']
            self.Did_LskinId_skinNameLD =[]

    def get_skinId_skinName_from_id(self ,id):
      url =f'https://pvp.qq.com/web201605/herodetail/{id}.shtml'
      response = requests.get(url)
      response.encoding = response.apparent_encoding
      soup =bs4.BeautifulSoup(response.text ,'lxml')

      heroName =soup.select('.cover-name').text
      print(f'正在整理{heroName}的数据...')
      L_skinName =soup.select('.pic-pf-list')['data-imgname'].split('|')
      for skinId ,baseSkinName in enumerate(L_skinName ,1):
            skinName =heroName +' ' +baseSkinName.split('&').replace(heroName ,'')
            self.Did_LskinId_skinNameLD.append()
      print('Done.\n')

    def endLoad(self ,id ,skinId ,skinName):
      url =f'http://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/{id}/{id}-bigskin-{skinId}.jpg'
      res =requests.get(url)
      with open(skinName+'.jpg' ,'wb') as f:
            f.write(res.content)


    def testMain(self):
      self.get_all_id()

      for id in self.Did_LskinId_skinNameLD:
            self.get_skinId_skinName_from_id(id)

      os.mkdir('王者_皮肤_结果')
      os.chdir('王者_皮肤_结果')
      for id ,L_skinInfo in self.Did_LskinId_skinNameLD.items():
            for skinID ,skinName in L_skinInfo:
                print(f'下载{skinName}中')
                self.endLoad(id ,skinID ,skinName)
                print('Done.\n')
      os.chdir(os.pardir)

try_ =WZskin()
try_.testMain()

昨天写的,用的逻辑可能和你的是一样的(补充完整基础url).可选写这个的逻辑用不到爬LOLl里(例如暴走萝莉 金克斯的 她的皮肤id顺序不是按1234这样连续的.而lol皮肤ld ,我好像没在html找到)
而且你的这个答案...如之前问的lol爬取问题一样 ,有爬取空图的风险...

丨游戏灬需要 发表于 2020-10-10 22:02:03

suchocolate 发表于 2020-10-10 19:13


我selenium学的不深 ,问下 ,这模块有没有设置浏览器''不阻止网站弹窗''的设置? ,其实还是那个问题 :
browser =selenium.webdriver.Firefox()
browser.execute_script(f'window.open("{url}")')
打不开超过20个页面(大概设置了就可以了)

suchocolate 发表于 2020-10-11 10:18:28

丨游戏灬需要 发表于 2020-10-10 21:21
class WZskin():
    def __init__(self):
      self.Did_LskinId_skinNameLD ={}


加个if判断是否为空,程序都是活学活用。

丨游戏灬需要 发表于 2020-10-11 11:14:01

suchocolate 发表于 2020-10-11 10:18
加个if判断是否为空,程序都是活学活用。

哦,这个优化我昨天想过 ,就是往软件上那种(生成缓存文件 ,加载缓存文件)的级别上写而已.可惜水平不够 ,还是有些难的.我慢慢想吧(但加个if判断 ,太简单粗暴了 ,不实用)

suchocolate 发表于 2020-10-11 15:19:59

丨游戏灬需要 发表于 2020-10-11 11:14
哦,这个优化我昨天想过 ,就是往软件上那种(生成缓存文件 ,加载缓存文件)的级别上写而已.可惜水平不够 ,还 ...

有的网站的html自身就不规范,有时返回空值很正常。
发一个你的筛查方式
页: [1]
查看完整版本: 关于selenium的