python爬虫学习第二十天
来源:互联网 发布:人民日报图文数据库 编辑:程序博客网 时间:2024/06/05 16:38
今天的练习是如何把 API 和网络数据采集结合起来:看看维基百科的贡献者们大都在哪里。
练习1 获取维基百科的匿名贡献者IP(test15.py)
from urllib.request import urlopenfrom bs4 import BeautifulSoupimport randomimport datetimeimport re# 获取内链接def getlinks(articleUrl): html = urlopen("http://en.wikipedia.org"+articleUrl) bsObj = BeautifulSoup(html) links = bsObj.find('div',{'id':'bodyContent'}).findAll('a',href = re.compile("^(/wiki/)((?!:).)*$")) return links pass# 获取匿名贡献者的ipdef getHistoryIps(pageUrl): pageUrl = pageUrl.replace("/wiki/", "") historyUrl = "http://en.wikipedia.org/w/index.php?title="+pageUrl+'&action=history' html = urlopen(historyUrl) bsObj = BeautifulSoup(html) ipAddresses = bsObj.findAll('a',{'class':'mw-anonuserlink'}) adresseslist=set() for ipAdress in ipAddresses: adresseslist.add(ipAdress.get_text()) return adresseslist passrandom.seed(datetime.datetime.now())links = getlinks("/wiki/Python_(programming_language)")while len(links)>0: for link in links: print('______________') addresses = getHistoryIps(link.attrs['href']) for address in addresses: print(address) newlink = links[random.randint(0,len(links)-1)] links = getlinks(newlink.attrs['href'])
在上面代码的第21行,有这样一条语句:adresseslist=set()。使用set()关键字建立的变量adresseslist是一个集合变量,关于集合变量的知识这里特别介绍一下。
Python 的集合类型简介
到现在为止,我用已经用过两个 Python 的数据结构来储存不同类型的数据:列表和词 典。已经有了两种数据类型,为什么还要用集合(set)? Python 的集合是无序的,就是说你不能用位置来获得集合元素对应的值。数据加入集 合的顺序,和你重新获取它们的顺序,很可能是不一样的。在上面的示例代码中,使 用集合的一个好处就是它不会储存重复值。如果你要存储一个已有的值到集合中,集 合会自动忽略它。因此,我们可以快速地获取历史编辑页面中独立的 IP 地址,不需要 考虑同一个编辑者多次编辑历史的情况。
对于未来可能需要扩展的代码,在决定使用集合还是列表时,有两件事情需要考虑:虽然列表迭代速度比集合稍微快一点儿,但集合查找速度更快(确定一个对象是否在 集合中) ,因为 Python 集合就是值为 None 的词典,用的是哈希表结构,查询速度为 O(1)。
练习2 小改动:将找到的IP地址用API定位地理位置
from urllib.request import urlopenfrom urllib.error import HTTPErrorfrom bs4 import BeautifulSoupimport randomimport datetimeimport reimport json# 获取内链接def getlinks(articleUrl): html = urlopen("http://en.wikipedia.org"+articleUrl) bsObj = BeautifulSoup(html) links = bsObj.find('div',{'id':'bodyContent'}).findAll('a',href = re.compile("^(/wiki/)((?!:).)*$")) return links pass# 获取匿名贡献者的ipdef getHistoryIps(pageUrl): pageUrl = pageUrl.replace("/wiki/", "") historyUrl = "http://en.wikipedia.org/w/index.php?title="+pageUrl+'&action=history' html = urlopen(historyUrl) bsObj = BeautifulSoup(html) ipAddresses = bsObj.findAll('a',{'class':'mw-anonuserlink'}) adresseslist=set() for ipAdress in ipAddresses: adresseslist.add(ipAdress.get_text()) return adresseslist passdef getAddresses(historyIP): try: html = urlopen('http://freegeoip.net/json/'+historyIP) response = html.read().decode('utf-8') except HTTPError: return None jsonObj = json.loads(response) return jsonObj.get('country_code') passrandom.seed(datetime.datetime.now())links = getlinks("/wiki/Python_(programming_language)")while len(links)>0: for link in links: print('______________') addresses = getHistoryIps(link.attrs['href']) for address in addresses: print('IP: '+address+' is in: '+getAddresses(address)) newlink = links[random.randint(0,len(links)-1)] links = getlinks(newlink.attrs['href'])
在原来的基础上增加了一个getAddresses函数,用来调用API获取IP地址对应的物理位置。
阅读全文
0 0
- python爬虫学习第二十天
- python爬虫学习第二十五天
- python爬虫学习第二十八天
- python爬虫学习第二十九天
- 学习python的第二十天
- python爬虫学习第二十七天(补昨天)
- python第二十五天学习记录
- 第二十天学习笔记
- 第二十天学习记录
- Java学习第二十天
- python爬虫学习第二天
- python爬虫学习第四天
- python爬虫学习第六天
- python爬虫学习第十天
- python爬虫学习第十二天
- python爬虫学习第二十二天
- python爬虫学习第三十天
- python爬虫学习第四十天
- Spring启动时获取自定义注解的属性值
- mysql锁表机制分析--mysqlISAM
- 练习 2017-08-13 获取进程数据-编译和运行Java代码 问题在截图上 留待解决。
- BlockingQueue的使用
- poj3250翻译+题解(单调栈)
- python爬虫学习第二十天
- 二进制1的个数(剑指Offer)
- 自下而上的编程
- redis 内存管理zmalloc
- React-navigation 官方文档中文翻译(四) intro to Navigators
- Linux下的进程和作业概念,以及作业管理
- 博科光交详解
- java小程序数组版电话本1.0版本(有问题尚未解决)
- poj2559Largest Rectangle in a Histogram