【问题标题】:Website server redirects me but get 200 as status code网站服务器重定向我,但得到 200 作为状态码
【发布时间】:2021-02-11 09:01:33
【问题描述】:

我正在学习使用 python 进行网页抓取,并且作为一种进行多合一练习的方式,我正在尝试使用 Beautiful Soup 和 requests 模块作为我的主要工具来制作游戏目录。不过,问题出在处理与请求模块相关的句子时。

描述:

该练习是关于获取用于对第一页中以 A 字母开头的游戏进行分类的所有类型标签。每个页面显示大约或正好 30 个游戏,因此如果想要独立于字母访问特定页面,则必须以这种形式访问 url。

  1. https://vandal.elespanol.com/juegos/13/pc/letra/a/inicio/1
  2. https://vandal.elespanol.com/juegos/13/pc/letra/a/inicio/2
  3. https://vandal.elespanol.com/juegos/13/pc/letra/a/inicio/3

等等…… 事实上,每个字母主页都有以下形式: URL:https://vandal.elespanol.com/juegos/13/pc/letra/相当于https://vandal.elespanol.com/juegos/13/pc/letra/a/inicio/

通过我的方式从某些页面中刮取类型并不是什么大问题,但是如果我想将它们全部刮掉怎么办,我怎么知道我何时完成了从字母的所有游戏中刮取类型?

例如,当您请求 url https://vandal.elespanol.com/juegos/13/pc/letra/a/inicio/200 时,您会被重定向到相应的字母主页,这意味着前 30 场比赛,因为最终它没有更多的比赛可以返回。 所以在考虑到这一点的同时..我正在考虑验证从 requests.get() 响应中获得的 status_code,但得到 200 作为状态码,而在分析使用 Chrome 工具收到的包时,我得到 301 作为状态码。在程序结束时,我将抓取的流派保存到一个文件中。

这是图片。

这是代码

from bs4 import BeautifulSoup
import string
import requests
from string import ascii_lowercase



def write_genres_to_file(site_genres): 
    with open('/home/l0new0lf/Desktop/generos.txt', 'w') as file_:
        print(f'File "{file_.name}" OPENED to write {len(site_genres)} GENRES')
        counter = 1
        site_genres_length = len(site_genres)
        for num in range(site_genres_length):
            print('inside File Loop')
            if counter != 2:
                if counter == 3:
                    file_.write(f'{site_genres[num]}' + '\n')
                    print('wrote something')
                    counter = 0
                    
                else: file_.write(f'{site_genres[num]}')
                
            else: file_.write(f'{site_genres[num]:^{len(site_genres[num])+8}}')
            print(f'Wrote genre "{site_genres[num]}" SUCCESSFULLY!')
            counter +=1 

def get_tags():

    #TITLE_TAG_SELECTOR = 'tr:first-child td.ta14b.t11 div a strong'
    #IMG_TAG_SELECTOR = 'tr:last-child td:first-child a img'
    #DESCRIPTION_TAG_SELECTOR = 'tr:last-child td:last-child p'
    GENRES_TAG_SELECTOR = 'tr:last-child td:last-child div.mt05 p'
    GAME_SEARCH_RESULTS_TABLE_SELECTOR = 'table.mt1.tablestriped4.froboto_real.blanca'

    GAME_TABLES_CLASS = 'table transparente tablasinbordes'

    site_genres = []

    for i in ['a']:
        counter = 1

        while True:
            rq = requests.get(f'https://vandal.elespanol.com/juegos/13/pc/letra/{i}/inicio/{counter}')
            
            
            if rq: 
                print('Request GET: from ' + f'https://vandal.elespanol.com/juegos/13/pc/letra/{i}/inicio/{counter}' + ' Got Workable Code !')
                
            
            if rq.status_code == 301 or rq.status_code == 302 or rq.status_code == 303 or rq.status_code == 304:
                print(f'No more games in letter {i}\n**REDIRECTING TO **')
                break

            counter +=1
                            
            soup = BeautifulSoup(rq.content, 'lxml')
            main_table = soup.select_one(GAME_SEARCH_RESULTS_TABLE_SELECTOR)
            #print('This is the MAIN TABLE:\n' + str(main_table))
            game_tables = main_table.find_all('table', {'class': GAME_TABLES_CLASS})
            #print('These are the GAME TABLES:\n' + str(game_tables))
            for game in game_tables:

                genres_str = str(game.select_one(GENRES_TAG_SELECTOR).contents[1]).strip().split(' / ')
                for genre in genres_str:
                    if not genre in site_genres:
                        site_genres.append(genre)
            
            
    write_genres_to_file(site_genres)
    
            
get_tags()

所以,大致我的问题是我怎么知道我什么时候完成了以某个字母开头的所有游戏的抓取才能开始从下一个游戏中抓取游戏?

注意:如果返回的 html 结构与信件的第一页相同,或者可能评估我是否收到重复的游戏,我只会考虑在循环中每次进行比较。但我认为这不应该是我的方式。

真的欢迎任何帮助,对于非常冗长的问题描述,我感到非常抱歉,但认为这是必要的。

【问题讨论】:

    标签: python-3.x beautifulsoup python-requests


    【解决方案1】:

    我不会仅仅依赖状态码。即使对于那里的页面,您也可能会获得非200 状态。例如,如果您超过了他们robots.txt 中描述的一定数量,或者您的网络出现延迟或错误。

    所以,回答您的问题:“我如何确保我抓取了与某个字母相对应的所有页面?”。为确保这一点,您可以保存此回复BeautifulSoup Grab Visible Webpage Text 中的所有“可见文本”并对其内容进行哈希处理。当您点击相同的哈希时,您就知道您已经抓取/抓取了该页面。因此,您可以逐步继续下一个字母。

    作为哈希 sn-p 的示例,我将使用以下内容:

    def from_text_to_hash(url: str) -> str:
        """ Getting visible-text and hashing it"""
        url_downloaded = urllib.request.urlopen(url)
        soup = BeautifulSoup(url_downloaded, "lxml")
        visible_text = soup.title.text + "\t" + soup.body.text
        current_hash = str(hash(visible_text))
        return current_hash
    

    你在一组变量current_hash中跟踪

    【讨论】:

    • 非常感谢您的回答,它确实解决了手头的问题,但每封信大约有 200 页,每封都有很多文字要保存。就内存而言,将所有这些保存到内存中的 AFAIK 效率非常低。
    • 您不必保存文本,您可以提取可见文本,对其进行散列并将其散列存储在“集合”数据结构中。正如您所说,如果每个字母大约有 200 页,那么您将节省 200 哈希。哈希要短得多。希望这能解释:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 2013-07-02
    相关资源
    最近更新 更多