Python 找到《权游》粉丝最钟意的演员

640?wx_fmt=png

译者 | 刘畅

编辑 | 琥珀

出品 | AI科技大本营(id:rgznai100)

《权力的游戏》最终季近日已开播,看得爽么,国外一位小哥看剧和学 Python 两不误,利用 Selenium 爬取了《权力的游戏》粉丝网站演员的照片并做了相关分析。来看看他怎么做的。

一、Web自动化

Web 自动化是 Python 能干的一件很酷的事,你可以使用如下思路来编写一个 Python 脚本:

1、打开浏览器

2、自动访问特定网站

3、登录该站点

4、转到该网站的另一页面

5、查找最新的博文

6、打开那篇博文

7、提交评论 “写得好,鼓掌”

8、最后退出网站

这个过程看似不难,花 20 秒就可以搞定,但如果让一遍一遍这样做,谁都会被逼疯。例如,如果你的网站还在开发中,里面有 100 篇博客,你想给每篇博客发表评论来测试该功能。那就会需要花 100 篇博文 * 20 秒 = 大约 33 分钟。如果有多个测试阶段,那是不是要多次测试该功能?

另外,Web 自动化还可以应用在这些方面:

  • 自动化创建网站账户。

  • 在线课程中,从头到尾自动化监控。

  • 仅使用单个脚本就能在网站上推送 100 个评论的功能。

接下来,我们将自动化登录美剧《权力的游戏》的粉丝网站。

先安装好 Selenium 和 ChromeDriver 等配置然后就可以开始了。

什么是 Selenium?

Selenium 是我们用于 Web 自动化的 Python 库。Selenium 开发了一个 API,可以让第三方开发 Web 驱动程序与浏览器通信。这样,Selenium 团队可以专注于代码库维护更新,而另一个团队可以专注于中间件。

1driver = webdriver.Firefox()
2driver.get('https://www.hbo.com/game-of-thrones')
3driver.close()

以上代码表达的意思是:将 Firefox 设置为首选浏览器,将此链接传递给 Firefox,关闭 Firefox。

下面就正式开始了。

首先导入 Selenium 库:

1from selenium import webdriver
2from selenium.webdriver.common.keys import Keys
3from selenium.webdriver.support.ui import WebDriverWait
4from selenium.webdriver.support import expected_conditions as EC
5from selenium.common.exceptions import TimeoutException
6import time 

接下来登录网站:

 1def login_to_westeros (username, userpass):
2    ## Log in
3    driver.get('https://asoiaf.westeros.org/index.php?/login/')    
4    ## Log the details
5    print(username + " is logging into westeros.")
6    ## 2) Look for the login box on the page
7    textfield_username = driver.find_element_by_id('auth')
8    textfield_username.clear()
9    textfield_username.send_keys(username)
10    textfield_email = driver.find_element_by_id('password')
11    textfield_email.clear()
12    textfield_email.send_keys(userpass)
13
14    submit_button = driver.find_element_by_id('elSignIn_submit')
15    submit_button.click()
16
17    ## Log the details
18    print(username + " is logged in! -> westeros")

上面的代码首先指定了访问页面 URL,接着查找登录框、密码框,定位好之后输入账号和密码,提交就可以登录。

如何找到任何网站的登录框和密码框?

Selenium 库有一堆方便的方法来查找网页上的元素。可以提供一些函数:

  • find_element_by_id

  • find_element_by_name

  • find_element_by_xpath

  • find_element_by_class_name

以 asoiaf.westeros.com 为例:

640?wx_fmt=png
img

二、Web Scrapping

登录后就可以开始爬取网页图片信息了。过程三步走:Python 访问网页、BeautifulSoup 解析、提取人物图片。

代码编写如下:

 1# Import the libraries needed
2import requests
3import time
4from bs4 import BeautifulSoup
5
6# The URL to scrape
7url = 'https://www.popsugar.com/celebrity/Kit-Harington-Rose-Leslie-Cutest-Pictures-42389549?stream_view=1#photo-42389576'
8#url = 'https://www.bing.com/images/search?q=jon+snow&FORM=HDRSC2'
9
10# Connecting
11response = requests.get(url)
12
13# Grab the HTML and using Beautiful
14soup = BeautifulSoup (response.text, 'html.parser')
15
16#A loop code to run through each link, and download it
17for i in range(len(soup.findAll('img'))):
18
19    tag = soup.findAll('img')[i]
20    link = tag['src']
21
22    #skip it if it doesn't start with http
23    if "http" in full_link: 
24        print("grabbed url: " + link)
25
26        filename = str(i) + '.jpg'
27        print("Download: " + filename)
28
29        r = requests.get(link)
30        open(filename, 'wb').write(r.content)
31
32    else:
33        print("grabbed url: " + link)
34        print("skip")
35
36
37    time.sleep(1)Breaking down the code

使用 Python 访问网页

首先导入所需的库,然后将网页链接存到变量中。

  • Requesets 库用于执行各种 HTTP 请求。

  • Time 库用于在每个请求后等待一秒钟。

  • BeautifulSoup 库用于更轻松地搜索 DOM 树。

使用 BeautifulSoup 解析网页

接下来,将 URL 地址推送给 BeautifulSoup。

寻找内容

最后,使用 FOR 循环来获取内容。

以 FOR 循环开始,BeautifulSoup 能快速过滤,并找到所有的 img 标签,然后存储在临时数组中。使用 len 函数查询数组的长度。

1#A loop code to run through each link, and download it
2for i in range(len(soup.findAll('img'))):

代码中会有51个内容。

接下来,我们将返回 soup 对象,然后开始内容过滤。

1tag = soup.findAll('img')[i]
2   link = tag['src']

需要记住的是,For循环中,[i]代表一个数字。

因此,我们可以通过索引号来寻找到每一个存储下来的 img 内容。采用soup.findALL('img')[i] 的使用方法将其传递给 tag 变量。

1<img src="smiley.gif" alt="Smiley face" height="42" width="42">

下一步是 src 变量。

下载图片

到循环的最后一步,下载内容。这里面的代码设计解释一下:

1、IF语句实际上是用于测试站点,有时候抓取的图像是根网站的一部分,且是不想要的内容。所以如果使用IF语句可以忽略。

2、只抓取 .jpg 格式的图片。

3、添加打印命令,如果你想获取网页所有的链接或特定内容,也是可以的。

其中采用的是 requests.get(link)和open(filename,'wb').write(r.content) 代码。

1r = requests.get(link)
2open(filename, 'wb').write(r.content) 

原理:

1、Requests 获取链接。

2、Open 是 Python 的一个内置函数,可以打开或者创建文件,并给它写的权限,并将链接的内容写入文件。

 1#skip it if it doesn't start with http
2    if "http" in full_link: 
3        print("grabbed url: " + link)
4
5        filename = str(i) + '.jpg'
6        print("Download: " + filename)
7
8        r = requests.get(link)
9        open(filename, 'wb').write(r.content)
10
11    else:
12        print("grabbed url: " + link)
13        print("skip")
14
15    time.sleep(1)

Web Scraping 有很多有用的函数。以上的代码在抓取网站的图像时,需要修改后才能使用。

三、生成报告和数据

收集数据很容易,但解释数据很困难。这就是为什么现在对数据科学家的需求急剧增加。数据科学家通常使用 R 和 Python 等语言进行解释。

接下来,我们将使用 CSV 模块。如果我们面对的是一个巨大的数据集,比如50,000 行或更多,那就需要使用 Pandas 库。

我们需要做的是下载 CSV 库,让 Python 解释数据,根据问题查询,然后打印出答案。

640?wx_fmt=png
img

对比 Python 与 Excel 函数

你可能会有疑问:“当我可以轻松使用像= SUM或= COUNT这样的表格函数,或者过滤掉我不需要手动操作的行时,为什么要使用 Python 呢?”

与第1部分和第2部分中的所有其他自动化技巧一样,你绝对可以手动执行此操作。但想象一下,如果你每天必须生成一份新的报告。

过程案例

每年,《权力的游戏》的新闻网站 Winteriscoming.net 都会举办疯狂三月的活动。访问者将投票选出他们最喜欢的角色,获胜者将向上移动并与另一个人竞争。经过 6 轮投票,宣布获胜者。

640?wx_fmt=png
img

由于 2019 年投票仍在进行中,我们抓取了 2018 年 6 轮的数据并将其编译成 CSV 文件。此外,还添加了一些额外的背景数据(比如它们来自哪里),使报告内容更有趣。

640?wx_fmt=png
img

不过,基于这个报告,有些问题需要考虑:

  • 问题1:谁赢得了人气投票?

最简单的方式就是用公式把每行的数据相加,如=sum(E2:J2)

然后排序,就能得到获胜者了。

640?wx_fmt=png
img

Python方法如下:

 1## Include the code from above
2
3# Push the data to a dictionary
4total_score = {}
5
6# Pass each character and their final score into total_score dictionary
7for row in file_data:
8  total = (int(row[4]) +
9          int(row[5]) +
10          int(row[6]) +
11          int(row[7]) +
12          int(row[8]) +
13          int(row[9]) )
14
15  total_score[row[0]] = total
16
17# Dictionaries aren't sortable by default, we'll have to borrow from these two classes.
18# https://stackoverflow.com/questions/613183/how-do-i-sort-a-dictionary-by-value
19from operator import itemgetter
20from collections import OrderedDict
21
22sorted_score = OrderedDict(sorted(total_score.items(), key=itemgetter(1) ,reverse=True))
23# We get the name of the winner and their score
24winner = list(sorted_score)[0#jon snow
25winner_score = sorted_score[winner] #score
26
27print(winner + " with " + str(winner_score))
28## RESULT => Jon Snow with 12959

上面代码分别实现了 4 个功能:

1、使用循环获取每行数据

2、对每一个循环,使用公式=sum(E:J)相加

3、引入两个类来对字典排序

4、输出获胜者

为了帮助理解循环,下面是代码流程图:

640?wx_fmt=png
img
  • 问题2:谁在平均票数之上?

排名高的人,显然会得到更高的票数。因此,下一步事情就是计总和,然后根据参与的轮数进行划分。

代码实现如下:

 1## OLD CODE FROM QUESTION 1
2# Pass each character and their final score into total_score dictionary
3for row in file_data:
4  total = (int(row[4]) +
5          int(row[5]) +
6          int(row[6]) +
7          int(row[7]) +
8          int(row[8]) +
9          int(row[9]) )
10
11  total_score[row[0]] = total
12
13## NEW CODE
14# Pass each character and their final score into total_score dictionary
15for row in file_data:
16  total = (int(row[4]) +
17          int(row[5]) +
18          int(row[6]) +
19          int(row[7]) +
20          int(row[8]) +
21          int(row[9]) )
22
23  # NEW LINE - divide by how many rounds
24  new_total = total / int(row[2])
25  total_score[row[0]] = new_total
26
27# RESULT => Davos Seaworth with 2247.6666666666665

仅仅需要添加一行代码,就可以回答这个问题。

  • 问题3:谁是最受欢迎的维斯特洛人?

这个问题,对于表格函数很复杂,需要先求和,然后进行过滤,然后再排序得到。

640?wx_fmt=png
img

Python方法:

 1## OLD CODE FROM QUESTION 1
2# Pass each character and their final score into total_score dictionary
3for row in file_data:
4  total = (int(row[4]) +
5          int(row[5]) +
6          int(row[6]) +
7          int(row[7]) +
8          int(row[8]) +
9          int(row[9]) )
10
11  # NEW LINE - divide by how many rounds
12  new_total = total / int(row[2])
13
14  total_score[row[0]] = new_total
15
16## NEW CODE
17# Pass each character and their final score into total_score dictionary
18for row in file_data:
19
20  # Add IF-THEN statement
21  if (row[3] == 'other'):
22    total = (int(row[4]) +
23            int(row[5]) +
24            int(row[6]) +
25            int(row[7]) +
26            int(row[8]) +
27            int(row[9]) )
28  else:
29    total = 0
30
31  total_score[row[0]] = total
32
33# RESULT => Missandei with 4811

问题2仅添加了一行代码。

问题3添加一个IF-ELSE语句。

 1import csv
2
3# Import the data
4f_csv = open('winter-is-coming-2018.csv')
5headers = next(f_csv)
6f_reader = csv.reader(f_csv)
7file_data = list(f_reader)
8
9# Make all blank cells into zeroes
10# https://stackoverflow.com/questions/2862709/replacing-empty-csv-column-values-with-a-zero
11for row in file_data:
12  for i, x in enumerate(row):
13    if len(x)< 1:
14      x = row[i] = 0

以上的代码流程是:

1、导入csv模块

2、导入csv文件,并转换成名为file_data的列表。

  • Python读取文件的方式是将数据传递给对象

  • 然后删除头部

  • 将对象传递给读者,最后是列表

  • 注意:实际上,Python3中有一种更简洁的方法

3、为了可以使数据相加,作者将空白处填为了0

  • 有了这样的设置,就可以遍历数据然后回答上述问题。

总结

第一部分介绍了如何使用 Selenium 库进行 Web 自动化,第二部分介绍了如何使用 BeautifulSoup 抓取 Web 数据,第三部分介绍了使用 CSV 模块生成报告。当然,这几个部分之间都有内在联系,需要读者深刻领会。

当然,学习到最后,你是否学会快速收集《权力的游戏》里最喜爱演员的照片了呢?先行奉上,欢迎留言互动。

640?wx_fmt=png
马王  Jason Momoa

原文地址:

https://medium.freecodecamp.org/how-i-used-Python-to-analyze-game-of-thrones-503a96028ce6


/今日留言主题/

你用 Selenium 爬过什么网站?

(留言格式:Dayxx:blahblah)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值