- 1、介绍了Xpath如何在网站的XML中找我们需要爬取的属性值。
- 2、介绍了爬虫如何抓取网站信息。(抓取到交给Xpath解析)
- 3、小案例1:爬取豆瓣电影评论
- 4、小案例2:爬取链家网信息
- 5、小案例3:爬取图片
1.Xpath介绍
XPath 是一门在 XML 文档中查找信息的语言。
在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML 文档是被作为节点树来对待的。树的根被称为文档节点或者根节点。
1、xpath表达式的基本格式
XPath 使用"路径表达式(Path Expression)"来选取 XML 文档中的节点或者节点集。在形式上,这些路径表达式和我们在常规的电脑"文件系统"中看到的表达式非常相似。
- 斜杠(/)作为路径内部的分割符。
- 同一个节点有绝对路径和相对路径两种写法。
- 绝对路径(absolute path)必须 用"/"起首,后面紧跟根节点,比 如/step/step/....."。
- 相对路径(relative path)则是除了绝对路径以外的其他写法,比如 step/step,也就是不使用"/"起首。
- "."表示当前节点。
- ".."表示当前节点的父子节点。
2、选择节点的基本规则
3、选择节点的实例
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title lang="eng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>
[例1]
bookstore:选取bookstore元素的所有节点。
[例2]
/bookstore:选取跟节点bookstore,这是绝对路径的写法。
[例3]
bookstore/book:选取所有属于bookstore的子元素的book元素,这是绝对路径的写法。
[例4]
//book:选择所有的book子元素,而不管他们在文档中的位置。
2、简单爬虫与数据抓取
网络爬虫一个非常炫酷,同时又非常实用的技术,这个部分我们给大家介绍如何写程序去完成网络数据的抓取。
requests是一个很实用的Python HTTP客户端库,编写爬虫和测试服务器响应数据时经常会用到。
安装
要安装requests,最方便快捷的方法是使用pip进行安装。在命令行执行
pip install requests
请求
最简单的静态网页数据获取,需要先对网页进行请求,比如我们以腾讯新闻为例:
import requests
result = requests.get('http://www.sohu.com/')
help(requests)
2.1 状态码
我们可以从返回result的状态码中,了解到是否请求成功。
2.2 文件编码
我们的最终目的是获取显示在网页上的内容,文本字符串有不同的编码格式,咱们可以先从返回结果里做一个简单的了解。
2.3 返回的网页内容
从返回的结果result中,可以取出网页的内容
2.4 在URLs中传递参数
有时候我们需要在URL中传递参数,比如在采集百度搜索结果时,我们wd参数(搜索词)和rn参数(搜素结果数量),你可以手工组成URL,requests也提供了一种看起来很NB的方法:
2.5 设置超时时间
我们可以通过timeout属性设置超时时间,一旦超过这个时间还没获得响应内容,就会提示错误。
2.6 添加代理
爬虫爬取数据时为避免被封IP,经常会使用代理。requests也有相应的proxies属性。
2.7 请求头内容
请求头内容可以用r.request.headers来获取。
2.8 模拟登陆
有很多网站需要我们登录之后才能完成数据的抓取,requests同样支持提交表单(包含用户名和密码)进行登录。代码的示例如下:
3爬取豆瓣电影评论
3.1导入需要的库
import sys
import requests
import time
3.2设置url和http头
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36 Core/1.47.933.400 QQBrowser/9.4.8699.400',
}
url = 'https://movie.douban.com/subject/20495023/comments'
3.3获取数据
data = requests.get(url,headers)
3.4查看编码
data.encoding
out : 'utf-8'
data.status_code
out : 200
3.5lxml与解析
大家可以利用BeautifulSoup做解析,我们换一种更高效的解析器,叫做lxml,会通过Xpath路径表达式来定位节点位置。
from lxml import etree
selector = etree.HTML(data.text)
3.6抽取所有评论区域
comments = selector.xpath('//div[@class="comment"]')
3.7对评论区进行解析
1.初始化需要解析的值
# 初始化4个list用于存储信息
users = []
users_url = []
stars = []
comment_texts = []
2.获取评论区的不同属性数据
for comment in comments:
user = comment.xpath('.//h3/span[2]/a/text()')[0]
user_url = comment.xpath('.//h3/span[2]/a/@href')[0]
star = comment.xpath('.//h3/span[2]/span[2]/@class')[0][7:8]
comment_text = comment.xpath('.//p/text()')[0].strip()
users.append(user)
users_url.append(user_url)
stars.append(star)
comment_texts.append(comment_text)
3.8组合成数据帧
comment_dic = {'user':users, 'user_url':users_url, 'star':stars, 'comments':comment_texts}
import pandas as pd
comment_df = pd.DataFrame(comment_dic)
comment_df
获取的数据展示:
4、用requests抓取链家网信息
来动手做一个练习,做到学以致用。
这次,我们来爬取链家网的一些内容,用的工具依旧是大家熟悉的requests和BeautifulSoup
4.1准备工作
编写爬虫前的准备工作,我们需要导入用到的库,这里主要使用的是requests和lxml两个。还有一个Time库,负责设置每次抓取的休息时间。
import requests
import time
4.2抓取列表页
开始抓取前当然应该了解一下目标网站URL结构咯。
链家网的二手房列表页面共有100个,URL结构为http://bj.lianjia.com/ershoufang/pg9/ 其中
- bj表示城市(北京)
- /ershoufang/是频道名称(二手房)
- pg9是页面码。
我们要抓取的是北京的二手房频道,所以前面的部分不会变,属于固定部分,后面的页面码需要在1-100间变化,属于可变部分。将URL分为两部分,前面的固定部分赋值给url,后面的可变部分使用for循环遍历页面。
url = 'https://bj.lianjia.com/ershoufang/'
page = 'pg'
这里提一个小小的醒,我们最好在http请求中设置一个头部信息,否则很容易被封ip。头部信息网上有很多现成的,也可以使用httpwatch等工具来查看。
#设置请求头部信息
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
'Accept':'text/html;q=0.9,*/*;q=0.8',
'Accept-Charset':'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
'Accept-Encoding':'gzip',
'Connection':'close',
'Referer':'http://www.baidu.com/link?url=_andhfsjjjKRgEWkj7i9cFmYYGsisrnm2A-TN3XZDQXxvGsM9k9ZZSnikW2Yds4s&amp;wd=&amp;eqid=c3435a7d00146bd600000003582bfd1f'
}
我们使用for循环生成1-100的数字,转换格式后与前面的URL固定部分拼成要抓取的URL。这里设置每个页面间隔0.5秒。抓取到的页面保存到html中。
for i in range(1,2):#暂时抓第一页
if i == 1:
i = str(i)
tmp_url = url+'/'#第一页url为http://bj.lianjia.com/ershoufang/
r = requests.get(url=tmp_url, headers=headers)
html = r.text
else:
i = str(i)
tmp_url = url+page+i+'/'
r = requests.get(url=tmp_url, headers=headers)
html2 = r.text
html += html2
time.sleep(2)
4.2页面解析
页面抓取的工作算是完成了,内容在html中,下一步就要进行页面解析了。我们依旧使用xml对页面进行解析。
from lxml import etree
selector = etree.HTML(html)
完成页面解析后就可以对页面中的关键信息进行提取了。下面我们分别对房源的总价,房源信息和关注度三部分进行提取。 把页面div标签中class=priceInfo的部分提取出来,并使用for循环将其中每个房源的总价数据存在tp中。
houses = selector.xpath('//li[@class="clear"]') #读取出当前页面的房子
len(houses)
out: 30
#初始化定义房子名称,房子价格,房子相关信息,房子待看信息等的列表
houses_title = []
houses_price = []
houses_info = []
followers_info = []
来看看爬下来的房价数据
4.3做一个统一的解析
for house in houses:
house_title = house.xpath('.//div[@class="title"]/a/text()')[0]
house_price = house.xpath('.//div[@class="totalPrice"]/span/text()')[0]
house_info = house.xpath('.//div[@class="houseInfo"]/a/text()')[0]+house.xpath('.//div[@class="houseInfo"]/text()')[0]
follower_info = house.xpath('.//div[@class="followInfo"]/text()')[0]
houses_title.append(house_title)
houses_price.append(house_price)
houses_info.append(house_info)
followers_info.append(follower_info)
#定义存储房子信息的字典
house_dic = {'house_title':houses_title, 'house_price':houses_price, 'house_info':houses_info, 'follower_info':followers_info}
import pandas as pd
house_df = pd.DataFrame(house_dic)
house_df
爬取链家网的信息展示:
5爬取图片
导入库函数
import requests
打开网页,指定编码
url = 'http://tieba.baidu.com/p/5346036052'
html = requests.get(url)
html.encoding = 'utf-8'
正则获取图像url
from lxml import etree
selector = etree.HTML(html.text);
image_url = selector.xpath('//img[@class="BDE_Image"]/@src')
image_url
图像写入文件
img = requests.get(image_url[0])
with open('baidu_tieba.jpg', 'ab') as f:
f.write(img.content)
f.close()
酱油哥个人博客:https://enfangzhong.github.io/