感谢网页使用python或pyspark抓取多个页面

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了感谢网页使用python或pyspark抓取多个页面相关的知识,希望对你有一定的参考价值。

我正在尝试第一次网站抓一个网站,我想从网页抓取日本动画网站创建一个csv文件与标题,性别,工作室和动画的持续时间。

我只设法使用该代码收集第一页标题的数据:

import requests
from bs4 import BeautifulSoup
res = requests.get("http://www.animeka.com/animes/series/~_1.html")
soup = BeautifulSoup(res.content, "html.parser")
anime_containers = soup.find_all('table', class_ = 'animesindex')
names = []

for container in anime_containers:

    if container.find_all('td', class_ = 'animestxt') is not None:
        name = container.a.text
        names.append(name)

import pandas as pd

test_df = pd.DataFrame({'anime': names})
print(test_df)

得到这样的东西:

anime
0   "Eikou Naki Tensai-tachi" kara no Monogatari
1                                 "Eiyuu" Kaitai
2                              "Parade" de Satie
3                                       ?l DLIVE
4                   'n Gewone blou Maandagoggend
5                                    +Tic Neesan
6                          .hack// Terminal Disc
7                           .hack//G.U. Returner
8                            .hack//G.U. Trilogy

我不知道如何收集性别,工作室和持续时间以及如何刮掉所有其他页面而不重复相同的代码

这是页面视图源代码:http://www.animeka.com/animes/series/~_1.html

答案

要迭代所有页面,您只需使用for循环并更改URL中的页码,如下所示:

for page_no in range(1, 467):
    url = 'http://www.animeka.com/animes/~_{}.html'.format(page_no)

现在,要获取所需的信息,您可以使用:

titles, studios, genres, durations = [], [], [], []

for page_no in range(1, 467):
    url = 'http://www.animeka.com/animes/~_{}.html'.format(page_no)
    r = requests.get(url)
    soup = BeautifulSoup(r.text, 'lxml')

    for table in soup.find_all('table', class_='animesindex'):
        td = table.find_all('td', class_='animestxt')
        titles.append(td[1].text.split(':')[1])
        studios.append(td[3].text.split(':')[1])
        genres.append(td[4].text.split(':')[1])
        durations.append(td[6].text.split(':')[1])

headers = ['Title', 'Studio', 'Genres', 'Duration']
df = pd.DataFrame(dict(zip(headers, [titles, studios, genres, durations])))
print(df)

部分输出:

                                            Title                   Duration                                             Genres                                             Studio
0    "Eikou Naki Tensai-tachi" kara no Monogatari    TV-S 25 mins (en cours)                          [SPORT] [TRANCHE DE VIE]                      [NHK ENTERPRISE] [J.C. STAFF] 
1                                  "Eiyuu" Kaitai                      1 OAV                                         [COMéDIE]                                            [ZEXCS] 
2                               "Parade" de Satie             1 FILM 14 mins         [FANTASTIQUE & MYTHE] [COMéDIE] [MUSICAL]                               [YAMAMURA ANIMATION] 
3                                         elDLIVE               Non spécifié         [ACTION] [COMéDIE] [ESPACE & SCI-FICTION]                                 [PIERROT CO.,LTD.] 
4                    'n Gewone blou Maandagoggend              1 FILM 3 mins                                           [DRAME]                                            [AUCUN] 
另一答案

这个小程序显示了如何废弃一个可能帮助可能不是最佳解决方案的页面,您可以根据自己的需要进行修改:(从http://www.animeka.com/animes/series/~_1.htmlhttp://www.animeka.com/animes/series/~_466.html

import requests
from bs4 import BeautifulSoup

animation_list = []
url = "http://www.animeka.com/animes/series/~_1.html"
page_source = requests.get(url).content
soup = BeautifulSoup(page_source, "html5lib")
tag_list = soup.find_all("td", {"class" : "animestxt"})
result_list = []

for tag in tag_list:
    if "TITRE ORIGINAL" in tag.text:
        data_string = tag.text.split("\n")
        tmp_dic = {}
        for index in data_string:
            line = index.strip()
            if len(line) == 0:
                continue
            if not line[0].isalpha():
                continue
            if line not in ["", " ", "  "]:
                tmp_dic[line.split(":")[0]] = line.split(":")[1]
        result_list.append(tmp_dic)

for list_index in result_list:
    if len(list_index) != 6:
        continue
    for item in list_index:
        print("{} : {}".format(item, list_index[item]))
    print("==================")

输出:

TITRE ORIGINAL  :  "Eikou Naki Tensai-tachi" kara no Monogatari
ANNÉE DE PRODUCTION  :  2017
STUDIOS  :  [NHK ENTERPRISE] [J.C. STAFF]
GENRES  :  [SPORT] [TRANCHE DE VIE]
AUTEURS  :  [ITOU TOMOYOSHI] [MORITA SHINGO]
TYPE & DURÉE  :   TV-S 25 mins (en cours)
==================
TITRE ORIGINAL  :  "Eiyuu" Kaitai
ANNÉE DE PRODUCTION  :  2016
STUDIO  :  [ZEXCS]
GENRE  :  [COMéDIE]
AUTEUR  :  [KOYAMA KYOUHEI]
TYPE & DURÉE  :  1 OAV
==================
TITRE ORIGINAL  :  "Parade" de Satie
ANNÉE DE PRODUCTION  :  2016
STUDIO  :  [YAMAMURA ANIMATION]
GENRES  :  [FANTASTIQUE & MYTHE] [COMéDIE] [MUSICAL]
AUTEUR  :  [SATIE ERIK]
TYPE & DURÉE  :  1 FILM 14 mins
==================
TITRE ORIGINAL  :  elDLIVE
ANNÉE DE PRODUCTION  :  2017
STUDIO  :  [PIERROT CO.,LTD.]
GENRES  :  [ACTION] [COMéDIE] [ESPACE & SCI-FICTION]
AUTEUR  :  [AMANO AKIRA]
TYPE & DURÉE  :  Non spécifié
==================
TITRE ORIGINAL  :  'n Gewone blou Maandagoggend
ANNÉE DE PRODUCTION  :  2014
STUDIO  :  [AUCUN]
GENRE  :  [DRAME]
AUTEUR  :  [KAMFER RONELDA]
TYPE & DURÉE  :  1 FILM 3 mins
另一答案

您图书馆的好选择!我还建议使用urlpath库来简化请求。

pip install urlpath

尝试一下:

from bs4 import BeautifulSoup
from urlpath import URL
import pandas as pd

def scrape_page(url):
    res = url.get()
    soup = BeautifulSoup(res.content, "html.parser")
    anime_containers = soup.find_all('table', {'class':'animesindex'})
    anime_dictionary = {}
    for container in anime_containers:
        anime_name = container.find('td',{'class':'animestitle'}).a.text
        dic = {}
        for td in container.find_all('td', {'class':'animestxt'}):
            attr = [t.strip() for t in td.text.strip().split(':')]
            dic[attr[0]] = ':'.join(attr[1:])
            anime_dictionary[anime_name] = dic
    return anime_dictionary

url = URL('http://www.animeka.com/animes/~_{}.html'.format(1))
anime_dictionary = scrape_page(url)
df = pd.DataFrame(anime_dictionary)
print(df)

此代码适用于单个页面。 scrape_page函数接受urlpath对象并使用它来发出请求。我个人喜欢urlpath对象,因为它与pyhton的pathlib对象,urllib很好地接口,并且内置了请求。从那里,我们将页面解析为BeautifulSoup对象。在汤的find_all方法中,我传入了字典而不是使用关键字参数,因为在将此代码应用于未来项目时传递多个约束会更有用。最终,scrape_page函数返回字典字典,因为它是一个非常方便的结构,用于构造DataFrame并直接类似于DataFrame。

修改此功能的多页使用代码如下:

anime_dictionary = {}
for i in range(466):
    url = URL('http://www.animeka.com/animes/~_{}.html'.format(i+1))
    anime_dictionary.update(scrape_page(url))
df = pd.DataFrame(anime_dictionary)
df.to_csv('file_name.csv')

此后的结果将存在于一个相当大的pandas数据帧中。以下显示了结果的条目:

                                       .hack//G.U. Trilogy  \
ANNÉE DE PRODUCTION                                    2008   
ANNÉES DE PRODUCTION                                    NaN   
AUTEUR                                                  NaN   
AUTEURS                [PROJECT .HACK] [SADAMOTO YOSHIYUKI]   
GENRE                                                   NaN   
GENRES                   [ACTION] [AVENTURE] [ANIMATION 3D]   
STUDIO                                                  NaN   
STUDIOS                [CYBERCONNECT2] [BANDAI NAMCO GAMES]   
TITRE ORIGINAL                          .hack//G.U. Trilogy   
TYPE & DURÉE                                 1 FILM 85 mins   
VOLUMES, TYPE & DURÉE                                   NaN 

展望未来,要使功能更加动态,能够使用表格处理任何网页,应该不会太困难。

以上是关于感谢网页使用python或pyspark抓取多个页面的主要内容,如果未能解决你的问题,请参考以下文章

使用selenium webdriver+beautifulsoup+跳转frame,实现模拟点击网页下一页按钮,抓取网页数据

使用 PHP 或 Python 的网页抓取技术

如何用python抓取这个网页的内容?

scrapy递归抓取网页数据

使用python和beautifulsoup4抓取网页后重复数据

如何用python实现爬虫抓取网页时自动翻页