- 1、介紹了Xpath如何在網(wǎng)站的XML中找我們需要爬取的屬性值。
- 2、介紹了爬蟲如何抓取網(wǎng)站信息。(抓取到交給Xpath解析)
- 3、小案例1:爬取豆瓣電影評論
- 4、小案例2:爬取鏈家網(wǎng)信息
- 5、小案例3:爬取圖片
1.Xpath介紹
XPath 是一門在 XML 文檔中查找信息的語言。
在 XPath 中,有七種類型的節(jié)點:元素、屬性、文本、命名空間、處理指令、注釋以及文檔(根)節(jié)點。XML 文檔是被作為節(jié)點樹來對待的。樹的根被稱為文檔節(jié)點或者根節(jié)點。


1、xpath表達式的基本格式
XPath 使用"路徑表達式(Path Expression)"來選取 XML 文檔中的節(jié)點或者節(jié)點集。在形式上,這些路徑表達式和我們在常規(guī)的電腦"文件系統(tǒng)"中看到的表達式非常相似。
- 斜杠(/)作為路徑內(nèi)部的分割符。
- 同一個節(jié)點有絕對路徑和相對路徑兩種寫法。
- 絕對路徑(absolute path)必須 用"/"起首,后面緊跟根節(jié)點,比 如/step/step/....."。
- 相對路徑(relative path)則是除了絕對路徑以外的其他寫法,比如 step/step,也就是不使用"/"起首。
- "."表示當(dāng)前節(jié)點。
- ".."表示當(dāng)前節(jié)點的父子節(jié)點。
2、選擇節(jié)點的基本規(guī)則

3、選擇節(jié)點的實例
<?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元素的所有節(jié)點。
[例2]
/bookstore:選取跟節(jié)點bookstore,這是絕對路徑的寫法。
[例3]
bookstore/book:選取所有屬于bookstore的子元素的book元素,這是絕對路徑的寫法。
[例4]
//book:選擇所有的book子元素,而不管他們在文檔中的位置。






2、簡單爬蟲與數(shù)據(jù)抓取

網(wǎng)絡(luò)爬蟲一個非常炫酷,同時又非常實用的技術(shù),這個部分我們給大家介紹如何寫程序去完成網(wǎng)絡(luò)數(shù)據(jù)的抓取。
requests是一個很實用的Python HTTP客戶端庫,編寫爬蟲和測試服務(wù)器響應(yīng)數(shù)據(jù)時經(jīng)常會用到。

安裝
要安裝requests,最方便快捷的方法是使用pip進行安裝。在命令行執(zhí)行
pip install requests
請求
最簡單的靜態(tài)網(wǎng)頁數(shù)據(jù)獲取,需要先對網(wǎng)頁進行請求,比如我們以騰訊新聞為例:
import requests
result = requests.get('http://www.sohu.com/')
help(requests)
2.1 狀態(tài)碼
我們可以從返回result的狀態(tài)碼中,了解到是否請求成功。

2.2 文件編碼
我們的最終目的是獲取顯示在網(wǎng)頁上的內(nèi)容,文本字符串有不同的編碼格式,咱們可以先從返回結(jié)果里做一個簡單的了解。

2.3 返回的網(wǎng)頁內(nèi)容
從返回的結(jié)果result中,可以取出網(wǎng)頁的內(nèi)容




2.4 在URLs中傳遞參數(shù)
有時候我們需要在URL中傳遞參數(shù),比如在采集百度搜索結(jié)果時,我們wd參數(shù)(搜索詞)和rn參數(shù)(搜素結(jié)果數(shù)量),你可以手工組成URL,requests也提供了一種看起來很NB的方法:

2.5 設(shè)置超時時間
我們可以通過timeout屬性設(shè)置超時時間,一旦超過這個時間還沒獲得響應(yīng)內(nèi)容,就會提示錯誤。

2.6 添加代理
爬蟲爬取數(shù)據(jù)時為避免被封IP,經(jīng)常會使用代理。requests也有相應(yīng)的proxies屬性。


2.7 請求頭內(nèi)容
請求頭內(nèi)容可以用r.request.headers來獲取。

2.8 模擬登陸
有很多網(wǎng)站需要我們登錄之后才能完成數(shù)據(jù)的抓取,requests同樣支持提交表單(包含用戶名和密碼)進行登錄。代碼的示例如下:
3爬取豆瓣電影評論
3.1導(dǎo)入需要的庫
import sys
import requests
import time
3.2設(shè)置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獲取數(shù)據(jù)
data = requests.get(url,headers)
3.4查看編碼
data.encoding
out : 'utf-8'
data.status_code
out : 200
3.5lxml與解析
大家可以利用BeautifulSoup做解析,我們換一種更高效的解析器,叫做lxml,會通過Xpath路徑表達式來定位節(jié)點位置。
from lxml import etree
selector = etree.HTML(data.text)
3.6抽取所有評論區(qū)域
comments = selector.xpath('//div[@class="comment"]')
3.7對評論區(qū)進行解析
1.初始化需要解析的值
# 初始化4個list用于存儲信息
users = []
users_url = []
stars = []
comment_texts = []
2.獲取評論區(qū)的不同屬性數(shù)據(jù)
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組合成數(shù)據(jù)幀
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
獲取的數(shù)據(jù)展示:

4、用requests抓取鏈家網(wǎng)信息

來動手做一個練習(xí),做到學(xué)以致用。
這次,我們來爬取鏈家網(wǎng)的一些內(nèi)容,用的工具依舊是大家熟悉的requests和BeautifulSoup
4.1準(zhǔn)備工作
編寫爬蟲前的準(zhǔn)備工作,我們需要導(dǎo)入用到的庫,這里主要使用的是requests和lxml兩個。還有一個Time庫,負(fù)責(zé)設(shè)置每次抓取的休息時間。
import requests
import time
4.2抓取列表頁
開始抓取前當(dāng)然應(yīng)該了解一下目標(biāo)網(wǎng)站URL結(jié)構(gòu)咯。
鏈家網(wǎng)的二手房列表頁面共有100個,URL結(jié)構(gòu)為http://bj.lianjia.com/ershoufang/pg9/ 其中
- bj表示城市(北京)
- /ershoufang/是頻道名稱(二手房)
- pg9是頁面碼。
我們要抓取的是北京的二手房頻道,所以前面的部分不會變,屬于固定部分,后面的頁面碼需要在1-100間變化,屬于可變部分。將URL分為兩部分,前面的固定部分賦值給url,后面的可變部分使用for循環(huán)遍歷頁面。
url = 'https://bj.lianjia.com/ershoufang/'
page = 'pg'
這里提一個小小的醒,我們最好在http請求中設(shè)置一個頭部信息,否則很容易被封ip。頭部信息網(wǎng)上有很多現(xiàn)成的,也可以使用httpwatch等工具來查看。
#設(shè)置請求頭部信息
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循環(huán)生成1-100的數(shù)字,轉(zhuǎn)換格式后與前面的URL固定部分拼成要抓取的URL。這里設(shè)置每個頁面間隔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頁面解析
頁面抓取的工作算是完成了,內(nèi)容在html中,下一步就要進行頁面解析了。我們依舊使用xml對頁面進行解析。
from lxml import etree
selector = etree.HTML(html)
完成頁面解析后就可以對頁面中的關(guān)鍵信息進行提取了。下面我們分別對房源的總價,房源信息和關(guān)注度三部分進行提取。 把頁面div標(biāo)簽中class=priceInfo的部分提取出來,并使用for循環(huán)將其中每個房源的總價數(shù)據(jù)存在tp中。
houses = selector.xpath('//li[@class="clear"]') #讀取出當(dāng)前頁面的房子
len(houses)
out: 30
#初始化定義房子名稱,房子價格,房子相關(guān)信息,房子待看信息等的列表
houses_title = []
houses_price = []
houses_info = []
followers_info = []
來看看爬下來的房價數(shù)據(jù)

4.3做一個統(tǒng)一的解析
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
爬取鏈家網(wǎng)的信息展示:

5爬取圖片
導(dǎo)入庫函數(shù)
import requests
打開網(wǎng)頁,指定編碼
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/