python—我如何从这个网站上获取特定的数据,这些数据';什么在不断变化/更新?

python—我如何从这个网站上获取特定的数据,这些数据';什么在不断变化/更新?,python,web-scraping,beautifulsoup,request,Python,Web Scraping,Beautifulsoup,Request,网址为: 目前,我的代码如下: from bs4 import BeautifulSoup import requests import re site = 'https://pokemongo.gamepress.gg/best-attackers-type' page_data = requests.get(site, headers=headers) soup = BeautifulSoup(page_data.text, 'html.parser') check_gamepres

网址为:

目前,我的代码如下:

from bs4 import BeautifulSoup
import requests
import re

site = 'https://pokemongo.gamepress.gg/best-attackers-type'
page_data = requests.get(site, headers=headers)

soup = BeautifulSoup(page_data.text, 'html.parser')

check_gamepress = soup.body.findAll(text=re.compile("Strength"))
print(check_gamepress)
然而,我真的很想搜集某些数据,我真的遇到了麻烦。 例如,我将如何刮除显示以下内容的部分以获得最佳错误类型:

"Good typing and lightning-fast attacks. Though cool-looking, Scizor is somewhat fragile."
当一个更好的口袋妖怪出现时,这些信息显然可以像过去一样更新。那么,我如何在将来可能会更新的地方刮取这些数据,而不必在发生这种情况时进行代码更改呢


提前感谢您的阅读

由于HTML的组织方式,这个特定的站点有点困难。包含信息的相关标签实际上没有很多区别特征,因此我们必须稍微聪明一点。使事情复杂化的是,包含整个页面信息的div是同级的。我们还必须用一些独创性来弥补这种网页设计的滑稽

我确实注意到了一种模式,这种模式在整个页面中(几乎完全)是一致的。每个“类型”和基础部分分为3个部分:

  • 包含类型和口袋妖怪的div,例如
    黑暗类型:暴君
  • 包含“专业”和移动的div
  • 包含“评级”和评论的div
下面的基本思想是,我们可以开始通过这样一个过程来组织这种标记混乱:

  • 标识每个类型标题div
  • 对于这些div中的每一个,通过访问其同级来获取其他两个div
  • 从每个div中解析信息
  • 考虑到这一点,我提出了一个有效的解决方案。代码的主要部分由5个函数组成。一个用于查找每个部分,一个用于提取同级,三个函数用于解析每个div

    import re
    import json
    import requests
    from pprint import pprint
    from bs4 import BeautifulSoup
    
    def type_section(tag):
        """Find the tags that has the move type and pokemon name"""
        pattern = r"[A-z]{3,} Type: [A-z]{3,}"
        # if all these things are true, it should be the right tag
        return all((tag.name == 'div',
                    len(tag.get('class', '')) == 1,
                    'field__item' in tag.get('class', []),
                    re.findall(pattern, tag.text),
                    ))
    
    def parse_type_pokemon(tag):
        """Parse out the move type and pokemon from the tag text"""
        s = tag.text.strip()
        poke_type, pokemon = s.split(' Type: ')
        return {'type': poke_type, 'pokemon': pokemon}
    
    def parse_speciality(tag):
        """Parse the tag containing the speciality and moves"""
        table = tag.find('table')
        rows = table.find_all('tr')
        speciality_row, fast_row, charge_row = rows
        speciality_types = []
    
        for anchor in speciality_row.find_all('a'):
            # Each type 'badge' has a href with the type name at the end
            href = anchor.get('href')
            speciality_types.append(href.split('#')[-1])
    
        fast_move = fast_row.find('td').text
        charge_move = charge_row.find('td').text
        return {'speciality': speciality_types,
                'fast_move': fast_move,
                'charge_move': charge_move}
    
    def parse_rating(tag):
        """Parse the tag containing categorical ratings and commentary"""
        table = tag.find('table')
        category_tags = table.find_all('th')
        strength_tag, meta_tag, future_tag = category_tags
        str_rating = strength_tag.parent.find('td').text.strip()
        meta_rating = meta_tag.parent.find('td').text.strip()
        future_rating = meta_tag.parent.find('td').text.strip()
        blurb_tags = table.find_all('td', {'colspan': '2'})
    
        if blurb_tags:
            # `if` to accomodate fire section bug
            str_blurb_tag, meta_blurb_tag, future_blurb_tag = blurb_tags
            str_blurb = str_blurb_tag.text.strip()
            meta_blurb = meta_blurb_tag.text.strip()
            future_blurb = future_blurb_tag.text.strip()
        else:
            str_blurb = None;meta_blurb=None;future_blurb=None
    
        return {'strength': {
                    'rating': str_rating,
                    'commentary': str_blurb},
                'meta': {
                    'rating': meta_rating,
                    'commentary': meta_blurb},
                'future': {
                    'rating': future_rating,
                    'commentary': future_blurb}
                }
    
    def extract_divs(tag):
        """
        Get the divs containing the moves/ratings 
        determined based on sibling position from the type tag
        """
        _, speciality_div, _, rating_div, *_ = tag.next_siblings
        return speciality_div, rating_div
    
    def main():
        """All together now"""
        url = 'https://pokemongo.gamepress.gg/best-attackers-type'
        response = requests.get(url)
        soup = BeautifulSoup(response.text, 'lxml')
        types = {}
        for type_tag in soup.find_all(type_section):
            type_info = {}
            type_info.update(parse_type_pokemon(type_tag))
            speciality_div, rating_div = extract_divs(type_tag)
            type_info.update(parse_speciality(speciality_div))
            type_info.update(parse_rating(rating_div))
            type_ = type_info.get('type')
            types[type_] = type_info
        pprint(types) # We did it
        with open('pokemon.json', 'w') as outfile:
            json.dump(types, outfile)
    
    目前,整件事只有一个小问题。还记得我说过这个模式几乎是完全一致的吗?嗯,
    Fire
    类型在这里是一个奇怪的球,因为它包含了两个pokemon,所以
    Fire
    类型的结果是不正确的。我或一些勇敢的人可能会想出一个办法来解决这个问题。或者他们将来会选择一个火精灵


    这段代码、生成的json(经过修饰)和所用HTML响应的存档可以在中找到。

    太宽泛的问题。您可以尝试保存页面并检查差异。看看这个列表是否有其他格式:rss、json、xml。@LuisMuñoz我只是想知道如何首先提取这些数据,正确的方法是什么?如果我每次都要更新我的机器人,我想这很好,但我肯定更想知道如何刮去那部分,我会简单地用那句话的一部分来更改“强度”,还是有办法使用html标记来找到它?你可以试着写一个基于Xpath的解析器。此XPath将获得具有field\u item class:'//div[@class=“field\u item]的所有div标记的列表“。解析列表并保存为cvs或其他格式,然后使用它与将来的版本进行比较。如果您真的感兴趣,这不是一个很好的项目:)。@LuisMuñoz感谢您的快速回复!感谢您的帮助。是的,我正在研究这个问题,并使用beautifulsoup搜索“field_uu”项目“同样,但该页面上的几乎所有内容都使用了该标记,因此它返回了大量信息,有没有办法进一步获取我正在查找的确切数据?我在discord上运行一个机器人,基本上,每次有人输入时!数据水,我想机器人拉所有的信息,它可以关于最好的水类型。现在,我的机器人只能提供最好的口袋妖怪。@sytech这么认为!我想我可能只是做错了什么。难道所有“优势”的模式都不一样吗?我想我只能用汤了。身体。再找一次。非常感谢。非常感谢您的精彩解释!至于火的类型,我的机器人在创建嵌入时也遇到了问题,我做了类似的事情来解决这个问题:cut_gamepress_furth=cut_gamepress.split('&'),然后打印(cut_gamepress_furth[0]。可能现在需要修改我的所有代码,以便与您的解释相匹配。再次感谢您!)解释得很好,做得很完美!不用担心@sb2894。如果您对代码中的细节有任何疑问,请发表评论。干杯,欢迎来到SO!很高兴终于来到这里!最近刚开始自学Python 3,我对这个社区是多么棒感到震惊!