了演示浏览器和API的使用,我们将会研究Facebook的网站。目前,从月活用户数维度来看,Facebook是世界上最大的社交网络之一,因此其用户数据非常有价值。
图1所示为Packt出版社的Facebook页面。
当你查看该页的源代码时,可以找到最开始的几篇日志,但是后面的日志只有在浏览器滚动时才会通过AJAX加载。另外,Facebook还提供了一个移动端界面,正如第1章所述,这种形式的界面通常更容易抓取。该页面在移动端的展示形式如图9.6所示。
图1
图2
当我们与移动端网站进行交互,并使用浏览器工具查看时,会发现该界面使用了和之前相似的结构来处理AJAX事件,因此该方法无法简化抓取。虽然这些AJAX事件可以被逆向工程,但是不同类型的Facebook页面使用了不同的AJAX调用,而且依据我的过往经验,Facebook经常会变更这些调用的结构,所以抓取这些页面需要持续维护。因此,如第5章所述,除非性能十分重要,否则最好使用浏览器渲染引擎执行JavaScript事件,然后访问生成的HTML页面。
下面的代码片段使用Selenium自动化登录Facebook,并跳转到给定页面的URL。
from selenium import webdriver def get_driver(): try: return webdriver.PhantomJS() except: return webdriver.Firefox() def facebook(username, password, url): driver=get_driver() driver.get('https://facebook.com') driver.find_element_by_id('email').send_keys(username) driver.find_element_by_id('pass').send_keys(password) driver.find_element_by_id('loginbutton').submit() driver.implicitly_wait(30) # wait until the search box is available, # which means it has successfully logged in search=driver.find_element_by_name('q') # now logged in so can go to the page of interest driver.get(url) # add code to scrape data of interest here ...
然后,可以调用该函数加载你感兴趣的Facebook页面,并使用合法的Facebook邮箱和密码,抓取生成的HTML页面。
如第1章所述,抓取网站是在其数据没有给出结构化格式时的最末之选。而Facebook确实为绝大多数公共或私有(通过你的用户账号)数据提供了API,因此我们需要在构建加强的浏览器抓取之前,首先检查一下这些API提供的访问是否已经能够满足需求。
首先要做的事情是确定通过API哪些数据是可用的。为了解决该问题,我们需要先查阅其API文档。开发者文档的网址为https://developers.facebook.com/docs,在这里给出了所有不同类型的API,包括图谱 API,该API中包含了我们想要的信息。如果你需要构建与Facebook的其他交互(通过API或SDK),可以随时查阅该文档,该文档会定期更新并且易于使用。
此外,根据文档链接,我们还可以使用浏览器内的图谱 API探索工具,其地址为https://developers.facebook.com/tools/explorer/。如图3所示,探索工具是用来测试查询及其结果的很好的地方。
图3
在这里,我可以搜索API,获取PacktPub的Facebook页面ID。图谱探索工具还可以用来生成访问口令,我们可以用它来定位API。
想要在Python中使用图谱API,我们需要使用具有更高级请求的特殊访问口令。幸运的是,有一个名为facebook-sdk(https://facebook-sdk.readthedocs.io)的维护良好的库可以供我们使用。我们只需通过pip安装它即可。
pip install facebook-sdk
下面是使用Facebook的图谱API从Packt出版社页面中抽取数据的代码示例。
In [1]: from facebook import GraphAPI In [2]: access_token='....' # insert your actual token here In [3]: graph=GraphAPI(access_token=access_token, version='2.7') In [4]: graph.get_object('PacktPub') Out[4]: {'id': '204603129458', 'name': 'Packt'}
我们可以看到和基于浏览器的图谱探索工具相同的结果。我们可以通过传递想要抽取的额外信息,来获得页面中的更多信息。要确定使用哪些信息,我们可以在图谱文档中看到页面中所有可用的字段,文档地址为https://developers.facebook.com/docs/graph-api/reference/page/。使用关键字参数fields,我们可以从API中抽取这些额外可用的字段。
In [5]: graph.get_object('PacktPub', fields='about,events,feed,picture') Out[5]: {'about': 'Packt provides software learning resources, from eBooks to video courses, to everyone from web developers to data scientists.', 'feed': {'data': [{'created_time': '2017-03-27T10:30:00+0000', 'id': '204603129458_10155195603119459', 'message': "We've teamed up with CBR Online to give you a chance to win 5 tech eBooks - enter by March 31! http://bit.ly/2mTvmeA"}, ... 'id': '204603129458', 'picture': {'data': {'is_silhouette': False, 'url': 'https://scontent.xx.fbcdn.net/v/t1.0-1/p50x50/14681705_10154660327349459_7 2357248532027065_n.png?oh=d0a26e6c8a00cf7e6ce957ed2065e430&oe=59660265'}}}
我们可以看到该响应是格式良好的Python字典,我们可以很容易地进行解析。
图谱API还提供了很多访问用户数据的其他调用,其文档可以从Facebook的开发者页面中获取,网址为https://developers.facebook.com/docs/graph-api。根据所需数据的不同,你可能还需要创建一个Facebook开发者应用,从而获得可用时间更长的访问口令。
业在网站建设时,很多同时也做了手机端的网站,为了丰富网站的版面和内容,给网站添加了大量的图片做美化。网站的图片是一个网站能给用户最直观的信息表现,而对于搜索引擎而言,蜘蛛在随机抓取网站图片时候的识别能力还没有那么强。如果文字很少,图片很多也会给手机端网站SEO优化带来一定的困难。
抓取手机网站图片
不过,随着搜索引擎算法的不断成熟,现在百度也能抓取网站的图片,例如:网站的LOGO、以及和文章主题相关的图片等等。十堰网站建设公司SEO优化顾问经过长时间的观察,总结出了以下六种方法,协助我们优化网站和手机端的图片,以达到优化友好,迅速被录入的作用。
一、不要盗用图片尽量原创
尽量自己做图片,有很多免费的图片素材,我们可以通过拼接,做出我们需要的图片。
在平时工作的时候,发现和自己网站相关的图片可以先保存下来,在本地做出分类和标记。网站需要图片的时候,看看相关的图片,自己着手做一个图片。这是一个长期积累的过程,随之时间的增加,自己的素材量也会越来越大。熟练了再做图片就得心应手了。
图片版权
再这里特别要注意,现在很多图片是有版权的,一点不要去使用那些有版权的图片,不然不光会侵权,还会让搜索引擎降低对你网站的信任值。
二、网站图片保存路径
这个问题很多站长都没有注意,图片在传到到网站的时候,尽量把图片保存在一个目录下面,或者根据网站栏目做好相应的图片目录,上传的时候路径要相对固定,方便蜘蛛抓取,蜘蛛在访问到这个目录的时候就会“知道”这个目录里面保存的是图片;
图片文件命名最好使用一些有规律的或者意义的方法,可以使用时间、栏目名称或者网站名称来命名。例如:SEO优化下面的图片可以使用“SEOYH2018-6-23-36”这种命名,前面“SEOYH”是SEO优化的简拼,中间是时间,最后是图片的ID。
为什么要这么做呢?其实这样是培养搜索引擎蜘蛛抓取习惯,方便将来更快的识别网站图片内容。让蜘蛛抓的顺心了,网站被收录的几率就增加了,何乐而不为呢!
三、图片周围要有相关文字
文章的开头就说了,网站图片是能把信息直接呈现给用户一个方法,搜索引擎在抓取网站内容的时候,也会检测这篇文章是否有配图、视频或者表格等等,这些都是可以增加文章分数值的元素,其他的几个形式暂时不表,这里我们只说说关于图片周围相关文字的介绍。
图片符合主题
首先图片周边文字要与图片本身内容相符,例如你的文章说的是做网站优化,里面配图是一道菜谱的图片,这不是挂羊头卖狗肉么?用户的访问感会极差,搜索引擎通过相关算法识别这张图片以后,也会觉得图文不符,给你差评哦。
所以,每篇文章最少要配一张相应的图片,而且在图片的周围要出现和你网站标题相关的内容。不但能帮助搜索引擎理解图片,还可以增加文章的可读性、用户体验友好度以及相关性。
四、图片添加alt、title标签
许多站长在添加网站图片时可能没有留意这些细节,有的可能觉得麻烦,希望大家千万别有这种想法,这是大错特错的。
搜索引擎抓取网站图片的时候,atl标签是它首先抓取的,也是识别图片内容最重要的核心因素之一,图片的alt属性是直接告诉搜索引擎这是啥网站图片,以及这张要表达什么意思;
title标签是用户指向这张图片的时候,会显示的提示内容,这是增加用户体验度和增加网站关键词的一个小技巧。
alt和title标签
还有就是这两个属性,会给有阅读障碍的访问者提供访问的便利,例如:有盲人在访问你网站的时候,他看不到屏幕上的内容,可能是通过读屏软件来阅读的,如果有alt属性,软件会直接读出alt属性里的文字,给他们的访问提供方便。
五、图片的大小和分辨率
尽管两者看起来有些相同,但还是有很大的差别,相同大小的图片,分辨率更高的话,网站最终体积也会越大。这一点大家要搞清楚。
网站的上的图片,一直以来都提倡用尽量小的图片,去最大化呈现内容。为什么要这样呢?因为小尺寸的图片会加载的更快,不会让访问者等待太久,特别是手机访问的时候,由于手机上网速度和流量的限制,用户更愿意访问能立即打开的页面,小尺寸图片就更有优势了。
在这里我们尽量做好平衡,在图片不失真的情况下,尺寸最好尽量的小。现在有很多在线给图片瘦身的工具,各位站长可以去尝试一下,把网站的图片适当的压缩一下,一方面可以减少你服务器带宽的压力,另外还能给用户有流畅的体验。
六、手机端自动适应
很多站长都遇到过网站在电脑访问图片显示很正常,可是从手机端就会出现错位等等情况,这就是大尺寸的图片给不同尺寸的终端造成错位和显示不全的情况。
图片自适应手机端
其实这个问题很好解决,在添加图片的时候宽高最好不要使用绝对大小,使用百分比就解决了。具体说,CSS代码不能指定像素宽度:width:xxx px;只能指定百分比宽度:width: xx%;或者width:auto就可以了。
这样做的目的也是为了让百度的移动蜘蛛抓取的时候有个良好的体验,这也是为了更符合百度移动落地页体验。
以上介绍了在网站SEO优化如何抓取手机网站图片的一些技巧,其实本质就是为了给用户更好的访问体验。你做网站的时候本着这个目的,相信搜索引擎一定会青睐你的网站。
来源:十堰SEO优化顾问
来源:卢松松博客
者:Kerry Parker
翻译:田晓宁
校对:丁楠雅
本文约2900字,建议阅读10分钟。
本教程以在Fast Track上收集百强公司的数据为例,教你抓取网页信息。
作为一名数据科学家,我在工作中所做的第一件事就是网络数据采集。使用代码从网站收集数据,当时对我来说是一个完全陌生的概念,但它是最合理、最容易获取的数据来源之一。经过几次尝试,网络抓取已经成为我的第二天性,也是我几乎每天使用的技能之一。
在本教程中,我将介绍一个简单的例子,说明如何抓取一个网站,我将从Fast Track上收集2018年百强公司的数据:
Fast Track:http://www.fasttrack.co.uk/
使用网络爬虫将此过程自动化,避免了手工收集数据,节省了时间,还可以让所有数据都放在一个结构化文件中。
用Python实现一个简单的网络爬虫的快速示例,您可以在GitHub上找到本教程中所介绍的完整代码。
GitHub链接:https://github.com/kaparker/tutorials/blob/master/pythonscraper/websitescrapefasttrack.py
以下是本文使用Python进行网页抓取的简短教程概述:
准备开始
在开始使用任何Python应用程序之前,要问的第一个问题是:我需要哪些库?
对于web抓取,有一些不同的库需要考虑,包括:
在本例中我们使用Beautiful Soup。你可以使用Python包管理器 pip 安装Beautiful Soup:
pip install BeautifulSoup4
安装好这些库之后,让我们开始吧!
检查网页
要知道在Python代码中需要定位哪些元素,首先需要检查网页。
要从Tech Track Top 100 companies收集数据,可以通过右键单击感兴趣的元素来检查页面,然后选择检查。这将打开HTML代码,我们可以在其中看到每个字段包含在其中的元素。
Tech Track Top 100 companies链接:http://www.fasttrack.co.uk/league-tables/tech-track-100/league-table/
右键单击感兴趣的元素并选择“Inspect”,显示html元素。
由于数据存储在一个表中,因此只需几行代码就可以直接获取数据。如果您想练习抓取网站,这是一个很好的例子,也是一个好的开始,但请记住,它并不总是那么简单!
所有100个结果都包含在<tr> 元素的行中,并且这些在一页上都可见。情况并非总是如此,当结果跨越多个页面时,您可能需要更改网页上显示的结果数量,或者遍历所有页面以收集所有信息。
League Table网页上显示了包含100个结果的表。检查页面时,很容易在html中看到一个模式。结果包含在表格中的行中:
<table class="tableSorter">
重复的行<tr> 将通过在Python中使用循环来查找数据并写入文件来保持我们的代码最小化!
附注:可以做的另一项检查是网站上是否发出了HTTP GET请求,该请求可能已经将结果作为结构化响应(如JSON或XML格式)返回。您可以在检查工具的网络选项卡中进行检查,通常在XHR选项卡中进行检查。刷新页面后,它将在加载时显示请求,如果响应包含格式化结构,则使用REST客户端(如Insomnia)返回输出通常更容易。
刷新网页后,页面检查工具的网络选项卡
使用Beautiful Soup解析网页html
现在您已经查看了html的结构并熟悉了将要抓取的内容,是时候开始使用Python了!
第一步是导入将用于网络爬虫的库。我们已经讨论过上面的BeautifulSoup,它有助于我们处理html。我们导入的下一个库是urllib,它连接到网页。最后,我们将输出写入csv,因此我们还需要导入csv 库。作为替代方案,可以在此处使用json库。
# import librariesfrom bs4 import BeautifulSoupimport urllib.requestimport csv
下一步是定义您正在抓取的网址。如上一节所述,此网页在一个页面上显示所有结果,因此此处给出了地址栏中的完整url:
# specify the urlurlpage='http://www.fasttrack.co.uk/league-tables/tech-track-100/league-table/'
然后我们建立与网页的连接,我们可以使用BeautifulSoup解析html,将对象存储在变量'soup'中:
# query the website and return the html to the variable 'page'page=urllib.request.urlopen(urlpage)# parse the html using beautiful soup and store in variable 'soup'soup=BeautifulSoup(page, 'html.parser')
我们可以在这个阶段打印soup变量,它应该返回我们请求网页的完整解析的html。
print(soup)
如果存在错误或变量为空,则请求可能不成功。可以使用urllib.error模块在此时实现错误处理。
搜索html元素
由于所有结果都包含在表中,我们可以使用find 方法搜索表的soup对象。然后我们可以使用find_all 方法查找表中的每一行。
如果我们打印行数,我们应该得到101的结果,100行加上标题。
# find results within tabletable=soup.find('table', attrs={'class': 'tableSorter'})results=table.find_all('tr')print('Number of results', len(results))
因此,我们可以对结果进行循环以收集数据。
打印soup对象的前两行,我们可以看到每行的结构是:
<tr><th>Rank</th><th>Company</th><th class="">Location</th><th>Year end</th><th class="" style="text-align:right;">Annual sales rise over 3 years</th><th class="" style="text-align:right;">Latest sales £000s</th><th class="" style="text-align:right;">Staff</th><th class="">Comment</th><!-- <th>FYE</th>--></tr><tr><td>1</td><td><a href="http://www.fasttrack.co.uk/company_profile/wonderbly-3/"><span>Wonderbly</span></a>Personalised children's books</td><td>East London</td><td>Apr-17</td><td style="text-align:right;">294.27%</td><td style="text-align:right;">*25,860</td><td style="text-align:right;">80</td><td>Has sold nearly 3m customisable children’s books in 200 countries</td><!-- <td>Apr-17</td>--></tr>
表格中有8栏:Rank,Company,Location,Year End,Annual Sales Rise,Latest Sales, Staff and Comments,所有这些都是我们可以保存的感兴趣的数据。
网页的所有行的结构都是一致的(对于所有网站来说可能并非总是如此!)。因此,我们可以再次使用find_all 方法将每一列分配给一个变量,那么我们可以通过搜索<td> 元素来写入csv或JSON。
循环遍历元素并保存变量
在Python中,将结果附加到一个列表中是很有用的,然后将数据写到一个文件中。我们应该在循环之前声明列表并设置csv的头文件,如下所示:
# create and write headers to a list rows=[]rows.append(['Rank', 'Company Name', 'Webpage', 'Description', 'Location', 'Year end', 'Annual sales rise over 3 years', 'Sales £000s', 'Staff', 'Comments'])print(rows)
这将打印出我们添加到包含标题的列表的第一行。
你可能会注意到表格中有一些额外的字段Webpage和Description不是列名,但是如果你仔细看看我们打印上面的soup变量时的html,那么第二行不仅仅包含公司名称。我们可以使用一些进一步的提取来获取这些额外信息。
下一步是循环结果,处理数据并附加到可以写入csv的rows。
在循环中查找结果:
# loop over resultsfor result in results: # find all columns per result data=result.find_all('td') # check that columns have data if len(data)==0: continue
由于表中的第一行仅包含标题,因此我们可以跳过此结果,如上所示。它也不包含任何<td>元素,因此在搜索元素时,不会返回任何内容。然后,我们可以通过要求数据的长度为非零来检查是否只处理包含数据的结果。
然后我们可以开始处理数据并保存到变量中。
# write columns to variables rank=data[0].getText() company=data[1].getText() location=data[2].getText() yearend=data[3].getText() salesrise=data[4].getText() sales=data[5].getText() staff=data[6].getText() comments=data[7].getText()
以上只是从每个列获取文本并保存到变量。但是,其中一些数据需要进一步清理以删除不需要的字符或提取更多信息。
数据清理
如果我们打印出变量company,该文本不仅包含公司名称,还包含描述。我们然后打印sales,它包含不需要的字符,如脚注符号,最好删除。
print('Company is', company) # Company is WonderblyPersonalised children's books print('Sales', sales) # Sales *25,860
我们希望将company 分为公司名称和描述,我们可以用几行代码实现。再看一下html,对于这个列,有一个 <span> 元素只包含公司名称。此列中还有一个链接指向网站上的另一个页面,其中包含有关该公司的更多详细信息。我们将在稍后使用它!
<td><a href="http://www.fasttrack.co.uk/company_profile/wonderbly-3/"><span>Wonderbly</span></a>Personalised children's books</td>
要将company 分成两个字段,我们可以使用find方法保存<span>元素,然后使用strip 或replace 从company 变量中删除公司名称,这样它只留下描述。
要从sales中删除不需要的字符,我们可以再次使用strip和replace 方法!
# extract description from the name companyname=data[1].find('span', attrs={'class':'company-name'}).getText() description=company.replace(companyname, '') # remove unwanted characters sales=sales.strip('*').strip('?').replace(',','')
我们要保存的最后一个变量是公司网站。如上所述,第二列包含指向另一个页面的链接,该页面具有每个公司的概述。 每个公司页面都有自己的表格,大部分时间都包含公司网站。
检查公司页面上的url元素
要从每个表中抓取url并将其保存为变量,我们需要使用与上面相同的步骤:
查看一些公司页面,如上面的屏幕截图所示,网址位于表格的最后一行,因此我们可以在最后一行内搜索<a>元素。
# go to link and extract company website url=data[1].find('a').get('href') page=urllib.request.urlopen(url) # parse the html soup=BeautifulSoup(page, 'html.parser') # find the last result in the table and get the link try: tableRow=soup.find('table').find_all('tr')[-1] webpage=tableRow.find('a').get('href') except: webpage=None
也有可能出现公司网站未显示的情况,因此我们可以使用try except条件,以防万一找不到网址。
一旦我们将所有数据保存到变量中,我们可以在循环中将每个结果添加到列表rows。
# write each result to rows rows.append([rank, company, webpage, description, location, yearend, salesrise, sales, staff, comments])print(rows)
然后可以试着在循环外打印变量,在将其写入文件之前检查它是否符合您的预期!
写入输出文件
如果想保存此数据以进行分析,可以用Python从我们列表中非常简单地实现。
# Create csv and write rows to output filewith open('techtrack100.csv','w', newline='') as f_output: csv_output=csv.writer(f_output) csv_output.writerows(rows)
运行Python脚本时,将生成包含100行结果的输出文件,您可以更详细地查看这些结果!
尾语
这是我的第一个教程,如果您有任何问题或意见或者不清楚的地方,请告诉我!
原文标题:
Data Science Skills: Web scraping using python
原文链接:
https://towardsdatascience.com/data-science-skills-web-scraping-using-python-d1a85ef607ed
译者简介
田晓宁,质量管理专家,国际认证精益六西格玛黑带,19年从业经验;软件工程专家,拥有CMMI ATM证书,曾主导公司通过CMMI 5级评估;精通ISO9000和ISO27000体系,长期担任公司质量和信息安全主任审核员,每年审核超过50个项目或部门;拥有PMP证书,担任公司项目管理内训师,具有项目管理和系统开发实战经验。
— 完 —
关注清华-青岛数据科学研究院官方微信公众平台“THU数据派”及姊妹号“数据派THU”获取更多讲座福利及优质内容。
*请认真填写需求信息,我们会在24小时内与您取得联系。