# 第四章内容--处理不同的网站布局:
# 我们想在功能类似的网站上抓取类似内容时,往往这些网站的内容可能布局不一样(相同内容的标签可能不同),由于通常我们爬取的网站数量有限,
# 我们没有必要去开发比较一套统一的复杂的的算法或机器学习来识别页面上的哪些文字看起来像标题或段落,只需要手动的去检查网页元素,分别对
# 不同的网站采用不同的方式去爬取就好了: # 示例 1:书上的例子,不翻墙没法跑通。
import requests class Content:
def __init__(self, url, title, body):
self.url = url
self.title = title
self.body = body def getPage(url):
req = requests.get(url)
return BeautifulSoup(req.text, 'html.parser') def scrapeNYTimes(url):
bs = getPage(url)
title = bs.find('h1').text
lines = bs.select('div.StoryBodyCompanionColumn div p') # nytime独有的布局
body = '\n'.join([line.text for line in lines])
return Content(url, title, body) def scrapeBrookings(url):
bs = getPage(url)
title = bs.find('h1').text
body = bs.find('div', {'class', 'post-body'}).text # brookings独有的布局
return Content(url, title, body) url = 'https://www.brookings.edu/blog/future-development/2018/01/26/delivering-inclusive-urban-access-3-uncomfortable-truths/'
content = scrapeBrookings(url)
print('Title: {}'.format(content.title))
print('URL: {}\n'.format(content.url))
print(content.body) url = 'https://www.nytimes.com/2018/01/25/opinion/sunday/silicon-valley-immortality.html'
content = scrapeNYTimes(url)
print('Title: {}'.format(content.title))
print('URL: {}\n'.format(content.url))
print(content.body)
# 示例 2: 修改的示例 1
import requests
from bs4 import BeautifulSoup class Content:
def __init__(self, url, title, body):
self.url = url
self.title = title
self.body = body def getPage(url):
html = requests.get(url)
return BeautifulSoup(html.content,'html.parser') # 注,此处使用 html.text时将会导致乱码 def scrapeGushidaquan(url):
bs = getPage(url)
title = bs.find('h2').text
body = bs.find('div', {'class', 'tsrtInfo'}).text # Gushidaquan独有的布局
return Content(url, title, body) def scrapeRensheng5(url):
bs = getPage(url)
title = bs.find('h1').text
body = bs.find_all('p')[0].text # 段落 NavigableString对象.text为 string # Rensheng5独有的布局
return Content(url, title, body) url = 'https://www.gushidaquan.cc/'
content = scrapeGushidaquan(url)
print('Title: {}'.format(content.title))
print('URL: {}\n'.format(content.url))
print(content.body) print("-"*15) url = 'http://www.rensheng5.com/zx/onduzhe/'
content = scrapeRensheng5(url)
print('Title: {}'.format(content.title))
print('URL: {}\n'.format(content.url))
print(content.body)
Title: 故事大全
URL: https://www.gushidaquan.cc/   小三,是通过互联网流行起来的一个词,是对第三者的蔑称。是爱情小说及家庭伦理故事恒久的元素,也是当前不可否认的社会现象。在民间还有狐狸精、邪花等贬称。
今天故事大全小编给您推荐几篇关于小三的精彩故事。有的故事比较长,建议您边看边收藏哦。...
---------------
Title: 读者在线阅读
URL: http://www.rensheng5.com/zx/onduzhe/   《读者》是甘肃人民出版社主办的一份综合类文摘杂志,原名《读者文摘》。  《读者》杂志多年以来始终以弘扬人类优秀文化为己任,坚持“博采中外、荟萃精华、启迪思想、开阔眼界”的办刊宗旨,赢得了各个年龄段和不同阶层读者的喜爱与拥护。  《读者》被誉为“中国人的心灵读本”、“中国期刊第一品牌”。  >>> 读者文摘在线阅读---欢迎您。
# 我们还是有办法来处理针对不同网页布局的爬取的,即把 各网站的不同点:name,url,css选择器等信息作为参数传递给
# bs.find()或 bs.find_all()的 tag/tag_list,attribues_dict参数 ,或传递给 bs.select() 来定义网站的结构及目标数据的位置。 # 总结:
# 3个类:
# content--用来存储所获取的数据的相关信息
# Website--用类来存储目标数据所在网页的 name,url,titleTag,structure等信息
# Crawler--用来爬取数据:获取 bs,解析bs 获取 title,body对象,存储数据信息到 content对象。 # 有一点不明白: url为什么单独给,而不使用 website对象里的 url? class Content:
"""
用来存储所获取的数据的相关信息
"""
def __init__(self, url, title, body):
self.url = url
self.title = title
self.body = body def print(self): # 将 打印或数据持久化的工作封装到函数里。
"""
Flexible printing function controls output
"""
print('URL: {}'.format(self.url))
print('TITLE: {}'.format(self.title))
print('BODY:\n{}'.format(self.body)) class Website:
"""
用类来存储目标数据所在网页的 name,url,titleTag,structure等信息
"""
def __init__(self, name, url, titleTag, bodyTag):
self.name = name
self.url = url
self.titleTag = titleTag
self.bodyTag = bodyTag import requests
from bs4 import BeautifulSoup class Crawler:
# 获取 bs
def getPage(self, url):
try:
html = requests.get(url)
except requests.exceptions.RequestException:
return None
# return BeautifulSoup(html.text, 'html.parser')
return BeautifulSoup(html.content, 'html.parser') # 解析 bs获取 tag对象
def safeGet(self, pageObj, selector):
"""
Utilty function used to get a content string from a Beautiful Soup object and a selector.
Returns an empty string if no objectis found for the given selector
"""
selectedElems = pageObj.select(selector)
if selectedElems is not None and len(selectedElems) > 0:
return '\n'.join([elem.get_text() for elem in selectedElems])
return '' # 调用上面两个方法,并将获得的 tag对象 实例化存储到 Content对象里。
def parse(self, site_obj, url):
"""
调用 getPage()获取包含目标数据的 bs对象,使用 safeGet()解析 bs对象的 title和 body,非空时存储到 content里
"""
bs = self.getPage(url)
if bs is not None:
title = self.safeGet(bs, site_obj.titleTag)
body = self.safeGet(bs, site_obj.bodyTag)
if title != '' and body != '':
content = Content(url, title, body)
content.print() # 调用封装后的 print() if __name__=='__main__':
# # 将要爬取的目标网页的 name,url,tag,cssselector等信息存储在嵌套列表里:
# siteData = [
# ['O\'Reilly Media', 'http://oreilly.com', 'h1', 'section#product-description'],
# ['Reuters', 'http://reuters.com', 'h1', 'div.StandardArticleBody_body_1gnLA'],
# ['Brookings', 'http://www.brookings.edu', 'h1', 'div.post-body'],
# ['New York Times', 'http://nytimes.com', 'h1', 'div.StoryBodyCompanionColumn div p']
# ]
# # 将上述信息实例化成 website对象:
# websites = []
# for site in siteData:
# site_obj=Website(site[0], site[1], site[2], site[3])
# websites.append(site_obj) # crawler = Crawler()
# crawler.parse(websites[0], 'http://shop.oreilly.com/product/0636920028154.do')
# crawler.parse(websites[1], 'http://www.reuters.com/article/us-usa-epa-pruitt-idUSKBN19W2D0')
# crawler.parse(websites[2], 'https://www.brookings.edu/blog/techtank/2016/03/01/idea-to-retire-old-methods-of-policy-education/')
# crawler.parse(websites[3], 'https://www.nytimes.com/2018/01/28/business/energy-environment/oil-boom.html') # 将要爬取的目标网页的 name,url,tag,cssselector等信息存储在嵌套列表里:
siteData = [
['故事大全', 'http://www.brookings.edu', 'h2', 'div.bigtit'],
['人生故事', 'http://nytimes.com', 'p', 'div.zzinfo']
]
# 将上述信息实例化成 website对象:
websites = []
for site in siteData:
site_obj=Website(site[0], site[1], site[2], site[3])
websites.append(site_obj) crawler = Crawler()
crawler.parse(websites[0], 'https://www.gushidaquan.cc/')
crawler.parse(websites[1], 'http://www.rensheng5.com/zx/onduzhe/')
URL: https://www.gushidaquan.cc/
TITLE: 故事大全
每日
故事
爱情故事
鬼故事
故事会
奇谈怪事
民间故事
幽默故事
传奇故事
哲理故事
人生故事
范文
情话大全
健康资讯
BODY: 故事大全
上网看故事,首选故事大全,阅读量排名第一的故事网站! URL: http://www.rensheng5.com/zx/onduzhe/
TITLE:   《读者》是甘肃人民出版社主办的一份综合类文摘杂志,原名《读者文摘》。  《读者》杂志多年以来始终以弘扬人类优秀文化为己任,坚持“博采中外、荟萃精华、启迪思想、开阔眼界”的办刊宗旨,赢得了各个年龄段和不同阶层读者的喜爱与拥护。  《读者》被誉为“中国人的心灵读本”、“中国期刊第一品牌”。  >>> 读者文摘在线阅读---欢迎您。 读者在线阅读_读者文摘在线阅读
Copyright 人生屋 版权所有 BODY: 读者在线阅读
  《读者》是甘肃人民出版社主办的一份综合类文摘杂志,原名《读者文摘》。  《读者》杂志多年以来始终以弘扬人类优秀文化为己任,坚持“博采中外、荟萃精华、启迪思想、开阔眼界”的办刊宗旨,赢得了各个年龄段和不同阶层读者的喜爱与拥护。  《读者》被誉为“中国人的心灵读本”、“中国期刊第一品牌”。  >>> 读者文摘在线阅读---欢迎您。
[人生] 声名20-06-24
有原则的人生最幸福20-06-23
父亲的墨水20-06-22
与母亲相守50天20-06-22
你不是世界的中心20-06-22
海上的父亲20-06-22 [人物] 三老道喜图20-06-22
俯首甘为孺子牛20-06-22
靛蓝商人20-06-22
塬下写作20-06-22
我的小说有辣子和葱20-06-21
见客记20-06-20 [文苑] 海明威的红笔20-06-22
温柔的讲述者20-06-22
我在等你啊20-06-22
春天等不来20-06-21
生有时,寐有时20-06-21
我的目光清澈20-06-20 [社会] 经济学何为20-06-24
给跳蚤穿靴子20-06-24
科技智人20-06-24
常态化偏见20-06-24
相见恨晚20-06-24
帮助别人才是文明的起点20-06-24 [生活] 我的命运是一座花园20-06-24
夜航船20-06-22
当特色菜遇上口味菜20-06-22
为什么看过的电纸书容易忘20-06-22
三泡茶20-06-22
被疫情改变的习惯20-06-22 [文明] 宋画里的医者日常20-06-22
饭不厌诈20-06-22
孤独的52赫兹20-06-20
用人之策20-06-20
“卫生”之起源20-05-22
绘画中的食物20-05-22 [点滴] 蛇与仙鹤20-06-24
真痴20-06-24
山的意义20-06-24
欲望20-06-21
傻气与福气20-06-21
鞋子20-06-21

Spider_基础总结7_爬虫基本模板(3个类)的更多相关文章

  1. python爬虫-基础入门-python爬虫突破封锁

    python爬虫-基础入门-python爬虫突破封锁 >> 相关概念 >> request概念:是从客户端向服务器发出请求,包括用户提交的信息及客户端的一些信息.客户端可通过H ...

  2. python基础整理6——爬虫基础知识点

    爬虫基础 什么是爬虫: 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁. ...

  3. C++ 类模板一(类模板的定义)

    //类模版语法 #include<iostream> using namespace std; /* 类模板和函数模板深入理解 1.编译器并不是把函数模板处理成能处理任何类型的函数 2.编 ...

  4. CI 模板解析器类

    模板解析器类可以解析你的视图文件中的伪变量.它可以解析简单的变量或者以变量作为标签的结构.如果你以前没有用过模板引擎,那么伪变量如下所示: <html><head><ti ...

  5. 读书笔记 effective c++ Item 43 了解如何访问模板化基类中的名字

    1. 问题的引入——派生类不会发现模板基类中的名字 假设我们需要写一个应用,使用它可以为不同的公司发送消息.消息可以以加密或者明文(未加密)的方式被发送.如果在编译阶段我们有足够的信息来确定哪个信息会 ...

  6. 【C++】模板简述(三):类模板

    上文简述了C++模板中的函数模板的格式.实例.形参.重载.特化及参数推演,本文主要介绍类模板. 一.类模板格式 类模板也是C++中模板的一种,其格式如下: template<class 形参名1 ...

  7. C++入门经典-例9.3-类模板,简单类模板

    1:使用template关键字不但可以定义函数模板,而且可以定义类模板.类模板代表一族类,它是用来描述通用数据类型或处理方法的机制,它使类中的一些数据成员和成员函数的参数或返回值可以取任意数据类型.类 ...

  8. C++——模板、数组类

    1.函数模板:可以用来创建一个通用功能的函数,以支持多种不同形参,进一步简化重载函数的函数体设计. 声明方法:template<typename 标识符> 函数声明 求绝对值的模板 #in ...

  9. 来点基础的练习题吧,看见CSDN这类基础的代码不多

    来点基础的练习题吧,看见CSDN这类基础的代码不多 //正三角形 void ex03(){ int i,k=0, rows, space; printf("请输入三角形的层次:") ...

随机推荐

  1. 手把手教你AspNetCore WebApi:缓存(MemoryCache和Redis)

    前言 这几天小明又有烦恼了,系统上线一段时间后,系统性能出现了问题,马老板很生气,叫小明一定要解决这个问题.性能问题一般用什么来解决呢?小明第一时间想到了缓存. 什么是缓存 缓存是实际工作中非常常用的 ...

  2. 多测师讲解python_安装001.1

    Python+pycharm 一.Python安装 python现在主要就是python2和python3,目前python3最新是3.8,考虑稳定性我们用3.6,3.7等 第一步:下载Python安 ...

  3. 程序员的“三十而已”,你都30岁了,不会还在XXX吧?

    一部<三十而已>火了 太太们的包包鄙视链出圈了 有人的地方就有江湖 是的,程序员入圈是容易的 不需要4万的LV,更不需要限量版的爱马仕 只需要一件耐躁的格子衫 然而,程序员的30岁, 却说 ...

  4. nginx安全:配置allow/deny控制ip访问(ngx_http_access_module)

    一,nginx中allow/deny指令的用途 1, Nginx的deny和allow指令是由ngx_http_access_module模块提供, Nginx安装默认内置了该模块 2, nginx访 ...

  5. C++ Primer第5版 第二章课后练习

    练习2.1 C++ 语言规定short 和 int 至少 16 位, long 至少32位, long long 至少64位.带符号类型可以表示整数.负数或0, 无符号类型则仅能表示大于等于0的值Th ...

  6. C#中的SqlBulkCopy批量插入数据

    在C#中,我们可以使用sqlBulkCopy去批量插入数据,其他批量插入方法不在讨论. 1 /// <summary> 2 /// SqlBulkCopy批量插入数据 3 /// < ...

  7. Flink + 强化学习 搭建实时推荐系统

    如今的推荐系统,对于实时性的要求越来越高,实时推荐的流程大致可以概括为这样: 推荐系统对于用户的请求产生推荐,用户对推荐结果作出反馈 (购买/点击/离开等等),推荐系统再根据用户反馈作出新的推荐.这个 ...

  8. S10 TES的八强赛,创造了奇迹,看看比赛时网友们怎么说的

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理 我相信很多观众会和我一样吧,当TES赢下第一局后开始心怀侥幸,赢下第二局后觉 ...

  9. 链接WPA2-企业WIFI时出现无法链接到该网络,可以链接个人WIFI时的问题和解决方案

    因在一个问题上掉两次坑所以还是决定记录下来,方便以后查阅. 第一次因为要部署.net 应用程序要求使用TLS1.2,所以修改了操作系统的默认启用的安全协议类型,导致好多应用程序出问题. 第二次因为vs ...

  10. Vue 路由切换时页面内容刷新页面并更新数据

    第二次进入页面,页面路由参数已经改变,但是页面内容不会刷新 <keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM <keep-aliv ...