抓取大学排名
2018-02-05 17:16
393 查看
示例图片
1.0版本
2.0版本,封装函数
3.0版本,多线程
4.0版本,分布式爬虫(多线程+多进程)
1.0版本
import requests from lxml import etree max_requests = 5 requests_count = 0 # 抓取单个大学链接,如http://qianmu.iguye.com/哈佛大学 r = requests.get("http://qianmu.iguye.com/2018USNEWS世界大学排名") dom = etree.HTML(r.text) links = dom.xpath("//*[@id='content']/table/tbody/tr/td[2]/a/@href") for link in links: requests_count += 1 if requests_count > max_requests: break if not link.startswith("http://"): link = 'http://www.qianmu.org/%s'%link print(link) # 抓取表格内容 r = requests.get(link) dom = etree.HTML(r.text.replace("\t","")) # 抓取第一列的内容 keys = dom.xpath("//div[@id='wikiContent']/div[@class='infobox']/table/tbody/tr/td[1]//text()") # print(keys) # 抓取第二列的内容 cols = dom.xpath("//div[@id='wikiContent']/div[@class='infobox']/table/tbody/tr/td[2]") values = [",".join(col.xpath('.//text()')) for col in cols] # print(values) # info = {} # for i in range(len(keys)): # info[keys[i]] = values[i] info = dict(zip(keys, values)) print(info)
2.0版本,封装函数
import requests from lxml import etree # 入口页面地址 start_url = "http://qianmu.iguye.com/2018USNEWS世界大学排名" # 存放待抓取页面地址 link_queue = [] def fetch(url): """执行网页的抓取""" r = requests.get(url) # 返回抓取的页面内容并取出页面中的制表符 return r.text.replace("\t","") def parse(html): """解析入口页面""" dom = etree.HTML(html) # 获取页面中的表格每一行的第二列中的超链接 links = dom.xpath("//div[@id='content']/table/tbody/tr/td[2]/a/@href") # 将这些链接放入待抓取队列中 link_queue.extend(links) def parse_university(html): """解析大学详情页面""" dom = etree.HTML(html) # 选择出表格的父节点,以减少重复代码 infobox = dom.xpath("//div[@id='wikiContent']/div[@class='infobox']")[0] # 选择出表格中每一行的第一列中的文本 keys = infobox.xpath("./table/tbody/tr/td[1]//text()") # 选择出表格中每一行的第二列节点 cols = infobox.xpath(".//table/tbody/tr/td[2]") # 便利第二列的节点,病提取出每一个单元格中的文本 values = [",".join(col.xpath(".//text()")) for col in cols] # info = {} # for i in range(len(keys)): # info[keys[i]] = values[i] # print(info) # 讲第一列、第二列中的数据合并成一个字典,组成大学信息 info = dict(zip(keys, values)) print(info) if __name__ == "__main__": # 抓取并处理入口页面,提取首页内的大学页面链接 parse(fetch(start_url)) # 最大请求数 max_requests = 5 # 请求计数器 requests_count = 0 # 反转队列,以便先进先出 link_queue.reverse() while link_queue: # 获取最前面的一个链接 link = link_queue.pop() requests_count += 1 if requests_count > max_requests: break # 如果有不规则的链接,则补全 if not link.startswith("http://"): link = "http://qianmu.iguye.com/%s" % link # 抓取并处理大学详情页面 print(link) parse_university(fetch(link)) # print("%s links"% len(links))
3.0版本,多线程
import threading from queue import Queue import requests import time from lxml import etree # 入口页面地址 start_url = "http://qianmu.iguye.com/2018USNEWS世界大学排名" # 存放待抓取页面地址 link_queue = Queue() # 下载器线程数量 DOWNLOADER_NUM = 10 # 线程池 threads = [] # 统计下载链接的数量 download_pages = 0 def fetch(url): """执行网页的抓取""" r = requests.get(url) global download_pages download_pages += 1 # 返回抓取的页面内容并取出页面中的制表符 return r.text.replace("\t","") def parse(html): """解析入口页面""" dom = etree.HTML(html) # 获取页面中的表格每一行的第二列中的超链接 links = dom.xpath("//div[@id='content']/table/tbody/tr/td[2]/a/@href") # 将这些链接放入待抓取队列中 for link in links: # 如果有不规则的链接,则补全 if not link.startswith("http://"): link = "http://qianmu.iguye.com/%s" % link # 将链接放入下载队列 link_queue.put(link) def parse_university(html): """解析大学详情页面""" dom = etree.HTML(html) # 选择出表格的父节点,以减少重复代码 infobox = dom.xpath("//div[@id='wikiContent']/div[@class='infobox']")[0] # 选择出表格中每一行的第一列中的文本 keys = infobox.xpath("./table/tbody/tr/td[1]//text()") # 选择出表格中每一行的第二列节点 cols = infobox.xpath(".//table/tbody/tr/td[2]") # 便利第二列的节点,病提取出每一个单元格中的文本 values = [",".join(col.xpath(".//text()")) for col in cols] # 讲第一列、第二列中的数据合并成一个字典,组成大学信息 info = dict(zip(keys, values)) print(info) def downloader(): """下载器,主要执行下载和解析操作""" while True: # 从队列中读取一个链接,如果没有,则阻塞 link = link_queue.get() # 如果收到的链接是None,则退出循环 if link is None: break # 下载并解析大学详情网页 print(link) parse_university(fetch(link)) # 向队列发送任务完成信号 link_queue.task_done() print("remining queue: %s"%link_queue.qsize()) if __name__ == "__main__": # 抓取并处理入口页面,提取首页内的大学页面链接 start_time = time.time() parse(fetch(start_url)) for i in range(DOWNLOADER_NUM): t = threading.Thread(target=downloader) t.start() threads.append(t) # 让队列一直阻塞到全部任务完成 link_queue.join() # 向队列中发送DOWNLOADER_NUM个None for i in range(DOWNLOADER_NUM): link_queue.put(None) # 退出线程 for t in threads: t.join() print("download %s page in %.2f seconds"%(download_pages,time.time()-start_time))
4.0版本,分布式爬虫(多线程+多进程)
import signal import threading from queue import Queue import redis import requests import time from lxml import etree # 入口页面地址 start_url = "http://qianmu.iguye.com/2018USNEWS世界大学排名" # 存放待抓取页面地址 # link_queue = Queue() # 下载器线程数量 DOWNLOADER_NUM = 10 # 下载延迟 DOWNLOADER_DELAY = 0.1 # 线程池 threads = [] # 统计下载链接的数量 download_pages = 0 r = redis.Redis() thread_on = True def fetch(url): """执行网页的抓取""" r = requests.get(url) global download_pages download_pages += 1 # 返回抓取的页面内容并取出页面中的制表符 return r.text.replace("\t","") def parse(html): """解析入口页面""" dom = etree.HTML(html) # 获取页面中的表格每一行的第二列中的超链接 links = dom.xpath("//div[@id='content']/table/tbody/tr/td[2]/a/@href") # 将这些链接放入待抓取队列中 for link in links: # 如果有不规则的链接,则补全 if not link.startswith("http://"): link = "http://qianmu.iguye.com/%s" % link # 将链接放入下载队列 # link_queue.put(link) if r.sadd("qianmu.seen",link): r.rpush("qianmu.queue",link) def parse_university(html): """解析大学详情页面""" dom = etree.HTML(html) # 选择出表格的父节点,以减少重复代码 infobox = dom.xpath("//div[@id='wikiContent']/div[@class='infobox']")[0] # 选择出表格中每一行的第一列中的文本 keys = infobox.xpath("./table/tbody/tr/td[1]//text()") # 选择出表格中每一行的第二列节点 cols = infobox.xpath(".//table/tbody/tr/td[2]") # 便利第二列的节点,病提取出每一个单元格中的文本 values = [",".join(col.xpath(".//text()")) for col in cols] # 讲第一列、第二列中的数据合并成一个字典,组成大学信息 info = dict(zip(keys, values)) # print(info) r.lpush("qianmu.item",info) def downloader(i): """下载器,主要执行下载和解析操作""" while thread_on: # 从队列中读取一个链接,如果没有,则阻塞 link = r.lpop("qianmu.queue") # 如果收到的链接是None,则退出循环 if link: # 下载并解析大学详情网页 parse_university(fetch(link)) print("remining-%s queue: %s"%(i,r.llen("qianmu.queue"))) time.sleep(DOWNLOADER_DELAY) print("Thread-%s exit now..." % i) def signal_handler(signnum,frame): print("received CRTL+C, wait for exit gracfully...") global thread_on thread_on = False if __name__ == "__main__": # 抓取并处理入口页面,提取首页内的大学页面链接 start_time = time.time() parse(fetch(start_url)) for i in range(DOWNLOADER_NUM): t = threading.Thread(target=downloader,args=(i+1,)) t.start() threads.append(t) print("Thread(%s) started..." %t.name) signal.signal(signal.SIGINT,signal_handler) # 退出线程 for t in threads: t.join() # 计算程序执行消耗的时间 print("download %s page in %.2f seconds"%(download_pages,time.time()-start_time))
相关文章推荐
- 全国大学排名数据抓取
- 抓取大学排名
- 2018年最好大学排名数据抓取
- 2012-2013年世界大学计算机专业排名
- 大学重要证书排名,少些盲目性
- 2012年学科评估结果公布 大学排名第一学科统计(转载)
- 美媒全球大学排名:清华超麻理跃居计算机专业第一
- 网站如何被蜘蛛抓取并取得较好排名的优化技巧
- 2011美国大学计算机排名(研究生)
- python 抓取google play 各搜索词排名
- 中国最好大学排名
- 中国部分大学排名爬虫
- 美国大学最新排名备受关注 手握雅思高分做到万事无忧
- python3.x爬虫:爬取大学排名数据
- 2017计算机专业大学排名
- 大学重要证书排名和大学生应当常去的十大网站
- 2012年全国计算机专业大学排名
- 网站如何被蜘蛛抓取并取得较好排名的优化技巧
- 2018全球大学AI排名发布,中国高校表现强势!
- 2014年国外公布的中国内地大学排名18强名单