网页的组成:
一般由HTML,JavaScript,CSS三部分组成
HTML相当于一个房间的结构,CSS相当于房间的样式(装修),JavaScript相当于功能(电器)
常见HTML标签:
1. <div> </div>
标志着一个区域
2. <p> </p>
写文字内容
3. <li> </li>
列表
4. <img>
插入图片
5. <h1> </h1> <h2></h2>.....<h6> </h6>
代表不同字号的标题
6. <a href="">
a标签定义超链接,用于从一张页面链接到另一张页面。
最重要的属性是 href 属性,它指示链接的目标。
7. <head> </head>
head传递给浏览器的,我们是不可见的
解析网页:
使用beautifulSoup解析网页
Beautiful Soup的简介
Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据
Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
BeautifulSoup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,BeautifulSoup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。
BeautifulSoup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度。引用块内容
关于beautifulSoup的安装用法,具体可看一位大神的文章(http://cuiqingcai.com/1319.html)
copy selector和copy XPath 都是描述一个元素在网页中所在位置的方式
真实世界中的网页解析
用Requests+BeautifulSoup 爬取 Tripadvisor
第一步:服务器与本地的交换机制
request:向服务器发送请求,request方法有
我们只需知道两种最常用的方法 get和post
比如:我们点击一个网页是get方法,当我们发微博时候就是post方法
一般使用爬虫,只需掌握get方法就行
当使用get时,要发送的信息一般为:
GET/page_one.html HTTP/1.1
Host:www.sample.com
使用方法–GET page_one.html–一个网址 HTTP/1.1–使用http1.1协议 Host:…. –主网址,所要请求的网页链接
Response: 网页对我们的回应
网站会我们回应:
status_code:200
状态码,200代表请求成功 请求失败返回403/404
例子:
我们爬取tripadvisor这个界面中的图片与标签
from bs4 import BeautifulSoup #导入beautifulsoup
import requests
url='https://www.tripadvisor.cn/Attractions-g60763-Activities-New_York_City_New_York.html' #网址
wb_data=requests.get(url) #使用request获得请求,得到回应赋值给 wb_data
soup=BeautifulSoup(wb_data.text,'lxml') #解析网页 .text 将网页资料变得可读
print(soup)
运行后:
抓取《中央公园》标题:
(使用Google浏览器)鼠标放在中央公园->右键点击检查->蓝色区域为中央公园信息->右击copy->Copy selector
得到:#taplc_attraction_coverpage_attraction_0 > div:nth-child(1) > div > div > div.shelf_item_container > div:nth-child(1) > div.poi > div > div.item.name > a
此时有个注意点:
选择器
ul.det-infor > li:nth-of-type(3) > a 与 ul.det-infor > li:nth-child(3)>aBeautifulSoup 不识别通过 google开发者工具获取的CSS选择器nth-child(第几个子元素而且是特定元素),可以用nth-of-type(第几个特定元素)替换。
替换后为:
title=soup.select('#taplc_attraction_coverpage_attraction_0 > div:nth-of-type(1) > div > div > div.shelf_item_container > div:nth-of-type(1) > div.poi > div > div.item.name > a')
# 得到标题信息copy selector后放入select()中
print(title)
输出:
但我们不仅仅要抓取一个标题,而是抓取一类标题,所以要找到它们的共同点:
都有div class=”listing_title”,因此可以写为:
(这个查找可使用chrome应用商店中的selectorgadget)
titles=soup.select('div.listing_title > a') #div listing_title下的a标签
soup下的select()是来查找特定标签中的内容
此时有很多标题,所以返回的titles是一个列表,由[]包括
可以返回列表第一个元素:
titles=soup.select('div.listing_title > a')
print(titles[0])
若要提取标签中的文字:
titles=soup.select('div.listing_title > a')
print(titles[0].text)
如果要提取所有标签:
from bs4 import BeautifulSoup #导入beautifulsoup
import requests
url='https://www.tripadvisor.cn/Attractions-g60763-Activities-New_York_City_New_York.html'
wb_data=requests.get(url) #使用request获得请求,得到回应赋值给response
soup=BeautifulSoup(wb_data.text,'lxml') #解析网页
titles=soup.select('#ATTR_ENTRY_ .listing_title > a')
for title in titles:
print(title.text)
输出:
同样爬取图片:
我们需要是大图片而不是小图片,因此可根据图片width属性来选择爬取图片:
imgs=soup.select('img[width="180"]') #img标签,[]中是标签的属性,width是180的
print(imgs)
输出:
如果我们只需要输出图片的链接,即图片中的src=“http://….”
imgs=soup.select('img[width="180"]')
for img in imgs:
print(img['src']) #或者img.get('src')
但此时我们发现图片都是重复的,而图片抓不到的原因是因为网站做了反扒取得手段,而这个案例就是js控制了图片,当我们在请求中,不会加载到代码中
接着我们同样爬取分类标签(方法和爬取标题类似):
要满足标签多对一的关系,因此从父级就停下来
也就是div class=”p13n_reasoning_v2”
cates=soup.select('div.p13n_reasoning_v2')
print(cates)
输出: