Phython—实训day5—爬虫相关知识
1爬蟲練習(urllib+xpath)
爬取某公司官網新聞中心板塊(“http://www.tipdm.com/xwzx/index.jhtml”)中的新聞標題和新聞內容,爬取頁數為5頁。?要求:使用urllib庫實現HTTP請求的發送,使用Xpath進行網頁解析,最后將爬取到的內容保存至Excel文件中。
1.1第一頁數據的爬取
#導入相應庫 from urllib import request from lxml import etree import pandas as pd #安裝命令:pip install pandas -i http://pypi.douban.com/simpleurl = 'http://www.tipdm.com/xwzx/index.jhtml' #第一頁的網頁鏈接 #發送請求 req = request.Request(url) #打開響應的對象 response = request.urlopen(req) #獲取響應的內容 html = response.read()#解析網頁 html = etree.HTML(html) #獲取數據 title = html.xpath('//*[@id="t505"]/div/div[3]/h1/a/text()') #新聞標題 content = html.xpath('//*[@id="t505"]/div/div[3]/div/text()') #新聞內容#將數據存儲為數據框DataFrame data = pd.DataFrame({'新聞標題':title, '新聞內容':content}) #將數據保存為Excel文件 data.to_excel(r'F:\Desktop\data.xlsx')1.2多頁數據的爬取
思路:首先把所有的網頁鏈接存放到一個列表中,然后循壞這一個網頁鏈接列表中的每一個鏈接,向每一個鏈接發送請求、網頁解析、獲取數據。此時獲取到的數據只是單個頁面的數據,所以需要在循壞外構建一個空的DataFrame用于存放所有頁面的數據。最后將這個包含有總數據的DataFrame保存為excel文件。
#導入相應的庫 from urllib import request from lxml import etree import pandas as pd#獲取前5頁網頁鏈接 urls = [] #構建空列表存放網頁鏈接 for i in range(1, 6):u = 'http://www.tipdm.com/xwzx/index_'+ str(i) + '.jhtml'urls.append(u) #向列表添加一個一個的鏈接 urls#獲取前5頁的網頁內容 all_data = pd.DataFrame() #構建空的DataFrame for j in urls:#發送請求req = request.Request(j)#打開響應的對象response = request.urlopen(req)#獲取響應的內容html = response.read()#解析網頁html = etree.HTML(html)#獲取數據title = html.xpath('//*[@id="t505"]/div/div[3]/h1/a/text()') #新聞標題content = html.xpath('//*[@id="t505"]/div/div[3]/div/text()') #新聞內容#將數據存儲為數據框DataFramedata = pd.DataFrame({'新聞標題':title, '新聞內容':content})#數據縱向合并all_data = pd.concat([all_data, data], axis=0)#將全部數據保存為Excel文件 all_data.to_excel(r'F:\Desktop\all_data.xlsx')2requests庫實現HTTP請求
requests庫生成請求的代碼非常便利,其使用的request方法的語法格式如下:
requests.get(url,**kwargs)
2.1發送請求
import requests #安裝命令:pip install requests -i http://pypi.douban.com/simple --trusted-host pypi.douban.comrq = requests.get('http://www.tipdm.com/') print('響應碼:', rq.status_code) #返回200,表示訪問成功 print('編碼:', rq.encoding) print('獲取內容:', rq.text) print('獲取內容:', rq.content) #二進制文本呈現2.2亂碼情況
#設置亂碼 rq.encoding = 'gbk' print('獲取內容:', rq.text) print('獲取內容:', rq.content)2.2.1亂碼修改第一種方法:手動指定
可以直接查看網頁源碼中的charset屬性得到該網頁的編碼。
##針對text輸出 rq.encoding = 'UTF-8' print('獲取內容:', rq.text)##針對content輸出,需要使用decode進行解碼 print('獲取內容:', rq.content.decode('utf-8'))2.2.2亂碼修改第二種方法:自動檢測
chardet庫是一個非常優秀的字符串∕文件編碼檢測模塊。chardet庫使用detect方法檢測給定字符串的編碼,detect方法常用的參數及其說明如下。
#重新設置以亂碼形式呈現 rq.encoding = 'gbk' print('獲取內容:', rq.text) import chardet #安裝命令:pip install chardet -i http://pypi.douban.com/simple --trusted-host pypi.douban.comrq.encoding = chardet.detect(rq.content)['encoding'] #chardet.detect(rq.content)返回的是字典形式的數據 print('獲取內容:', rq.text) #修改成功2.3爬蟲練習requests+xpath
import requests from lxml import etree import pandas as pd#獲取前5頁網頁鏈接 urls = [] #構建空列表存放網頁鏈接 for i in range(1, 6):u = 'http://www.tipdm.com/xwzx/index_'+ str(i) + '.jhtml'urls.append(u) #向列表添加一個一個的鏈接#獲取前5頁的網頁內容 all_data = pd.DataFrame() #構建空的DataFrame for j in urls:#發送請求rq = requests.get(j)#解析網頁html = etree.HTML(rq.text)#獲取數據title = html.xpath('//*[@id="t505"]/div/div[3]/h1/a/text()') #新聞標題content = html.xpath('//*[@id="t505"]/div/div[3]/div/text()') #新聞內容#將數據存儲為數據框DataFramedata = pd.DataFrame({'新聞標題':title, '新聞內容':content})#數據縱向合并all_data = pd.concat([all_data, data], axis=0)#將全部數據保存為Excel文件 all_data.to_excel(r'F:\Desktop\all_data.xlsx')3使用Beautiful Soup解析網頁
Beautiful Soup是一個可以從HTML或XML文件中提取數據的Python庫。目前Beautiful Soup 3已經停止開發,大部分的爬蟲選擇使用Beautiful Soup 4開發。Beautiful Soup不僅支持Python標準庫中的HTML解析器,還支持一些第三方的解析器,具體語法如下。
lxml解析器比較常用。
3.1創建BeautifulSoup對象
要使用Beautiful Soup庫解析網頁首先需要創建BeautifulSoup對象,將字符串或HTML文件傳入。
創建一個BeautifulSoup對象,使用格式如下。
BeautifulSoup("<html>data</html>") #通過字符串創建 BeautifulSoup(open("index.html")) #通過HTML文件創建import requests from bs4 import BeautifulSoup #pip install beautifulsoup4 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com#requests發送請求 rq = requests.get('http://www.tipdm.com/') #BeautifulSoup實現網頁解析 soup = BeautifulSoup(rq.text, 'lxml') #'lxml'表解析器3.2對象類型
3.2.1Tag對象類型
(1)Tag對象為HTML文檔中的標簽,形如
“<title>The Dormouse's story</title>”或“<p class="title"><b>The Dormouse's story</b></p>”等HTML標簽再加上其中包含的內容便是Beautiful Soup中的Tag對象。
(2)通過Tag的名稱屬性可以很方便的在文檔樹中獲取需要的Tag對象,通過該方法只能獲取文檔樹中第一個同名的Tag對象,而通過多次調用可獲取某個Tag對象下的分支Tag對象。通過find_all方法可以獲取文檔樹中的全部同名Tag對象。
soup.head #返回head標簽內容 soup.title #返回title標簽內容 soup.body.li #返回的是第一個li標簽 soup.find_all('li') #可返回所有li標簽 type(soup.head) #bs4.element.Tag(3)Tag有兩個非常重要的屬性:name和attributes。name屬性可通過name方法來獲取和修改,修改過后的name屬性將會應用至BeautifulSoup對象生成的HTML文檔。
a = soup.link a.name #name屬性返回的是標簽名稱 a.attrs #attrs屬性返回的是該標簽下面的屬性和屬性值3.2.2NavigableString對象類型NavigableString對象為包含在Tag中的文本字符串內容,如
“<title>The Dormouse‘s story</title>”中的“The Dormouse’s story”使用string的方法獲取,NavigableString對象無法被編輯,但可以使用replace_with的方法進行替換。
soup.title.string #可獲取到title標簽的文本內容 type(soup.title.string) #bs4.element.NavigableString#更改標簽里的文本內容 a = soup.title.string a.replace_with('廣東泰迪科技股份有限公司') #替換 soup.title.string3.2.3BeautifulSoup對象類型
BeautifulSoup對象表示的是一個文檔的全部內容。大部分時候,可以把它當作Tag對象。 BeautifulSoup對象并不是真正的HTML或XML的tag,所以并沒有tag的name和attribute屬性,但其包含了一個值為“[document]”的特殊屬性name。
type(soup) #bs4.BeautifulSoup soup.name #只返回[document]值 soup.attrs #BeautifulSoup對象類型沒有attribute屬性3.2.4Comment對象類型
Tag、NavigableString、BeautifulSoup幾乎覆蓋了html和xml中的所有內容,但是還有一些特殊對象,文檔的注釋部分是最容易與Tag中的文本字符串混淆的部分。Beautiful Soup庫中將文檔的注釋部分識別為Comment類型,Comment對象是一個特殊類型的NavigableString對象,但是當其出現在HTML文檔中時,Comment對象會使用特殊的格式輸出,需調用prettify方法。
markup = '<c><!--This is a markup--></b>' markup_soup = BeautifulSoup(markup, 'lxml') markup_soup.c.string type(markup_soup.c.string) #bs4.element.Comment3.3搜索特定節點并獲取其中的鏈接及文本
Beautiful Soup定義了很多搜索方法,其中常用的有find方法和find_all方法,兩者的參數一致,區別為find_all方法的返回結果是值包含一個元素的列表,而find直接返回的是結果。find_all方法用于搜索文檔樹中的Tag非常方便,其語法格式如下。
BeautifulSoup.find_all(name,attrs,recursive,string,**kwargs)
find_all方法的常用參數及其說明如下。
find_all方法
(1)可通過多種參數遍歷搜索文檔樹中符合條件的所有子節點。
(2)可通過name參數搜索同名的全部子節點,并接收多種過濾器。
(3)按照CSS類名可模糊匹配或完全匹配。完全匹配class的值時,如果CSS類名的順序與實際不符,將搜索不到結果。
(4)若tag的class屬性是多值屬性,可以分別搜索tag中的每個CSS類名。
(5)通過字符串內容進行搜索符合條件的全部子節點,可通過過濾器操作。
(6)通過傳入關鍵字參數,搜索匹配關鍵字的子節點。
import requests from bs4 import BeautifulSoup #pip install beautifulsoup4#requests發送請求 rq = requests.get('http://www.tipdm.com/') #BeautifulSoup實現網頁解析 soup = BeautifulSoup(rq.text, 'lxml') #'lxml'表解析器soup.find_all('title') #返回的是列表 soup.find('title') #直接返回結果#獲取標簽內容,使用get_text()方法 soup.find_all('title')[0].get_text() soup.find('title').get_text()soup.find('nav', class_="nav").find('ul', id="menu").find_all('li')[0].find('a').get_text() #class_ 這里加一個下劃線是因為避免與python關鍵字沖突所以用一個下劃線.?
?
總結
以上是生活随笔為你收集整理的Phython—实训day5—爬虫相关知识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 专访刘伟:软件开发人员的内功修炼之道
- 下一篇: 朱江洪功成身退 朱董配解体谁主格力(图)