① python網頁解析庫:用requests-html爬取網頁
Python 中可以進行網頁解析的庫有很多,常見的有 BeautifulSoup 和 lxml 等。在網上玩爬蟲的文章通常都是介紹 BeautifulSoup 這個庫,我平常也是常用這個庫,最近用 Xpath 用得比較多,使用 BeautifulSoup 就不大習慣,很久之前就知道 Reitz 大神出了一個叫 Requests-HTML 的庫,一直沒有興趣看,這回可算歹著機會用一下了。
使用 pip install requests-html 安裝,上手和 Reitz 的其他庫一樣,輕松簡單:
這個庫是在 requests 庫上實現的,r 得到的結果是 Response 對象下面的一個子類,多個一個 html 的屬性。所以 requests 庫的響應對象可以進行什麼操作,這個 r 也都可以。如果需要解析網頁,直接獲取響應對象的 html 屬性:
不得不膜拜 Reitz 大神太會組裝技術了。實際上 HTMLSession 是繼承自 requests.Session 這個核心類,然後將 requests.Session 類里的 requests 方法改寫,返回自己的一個 HTMLResponse 對象,這個類又是繼承自 requests.Response,只是多加了一個 _from_response 的方法來構造實例:
之後在 HTMLResponse 里定義屬性方法 html,就可以通過 html 屬性訪問了,實現也就是組裝 PyQuery 來干。核心的解析類也大多是使用 PyQuery 和 lxml 來做解析,簡化了名稱,挺討巧的。
元素定位可以選擇兩種方式:
方法名非常簡單,符合 Python 優雅的風格,這里不妨對這兩種方式簡單的說明:
定位到元素以後勢必要獲取元素裡面的內容和屬性相關數據,獲取文本:
獲取元素的屬性:
還可以通過模式來匹配對應的內容:
這個功能看起來比較雞肋,可以深入研究優化一下,說不定能在 github 上混個提交。
除了一些基礎操作,這個庫還提供了一些人性化的操作。比如一鍵獲取網頁的所有超鏈接,這對於整站爬蟲應該是個福音,URL 管理比較方便:
內容頁面通常都是分頁的,一次抓取不了太多,這個庫可以獲取分頁信息:
結果如下:
通過迭代器實現了智能發現分頁,這個迭代器裡面會用一個叫 _next 的方法,貼一段源碼感受下:
通過查找 a 標簽裡面是否含有指定的文本來判斷是不是有下一頁,通常我們的下一頁都會通過 下一頁 或者 載入更多 來引導,他就是利用這個標志來進行判斷。默認的以列表形式存在全局: ['next','more','older'] 。我個人認為這種方式非常不靈活,幾乎沒有擴展性。 感興趣的可以往 github 上提交代碼優化。
也許是考慮到了現在 js 的一些非同步載入,這個庫支持 js 運行時,官方說明如下:
使用非常簡單,直接調用以下方法:
第一次使用的時候會下載 Chromium,不過國內你懂的,自己想辦法去下吧,就不要等它自己下載了。render 函數可以使用 js 腳本來操作頁面,滾動操作單獨做了參數。這對於上拉載入等新式頁面是非常友好的。
② python爬蟲時,bs4無法讀取網頁標簽中的文本
稍微說一下背景,當時我想研究蛋白質與小分子的復合物在空間三維結構上的一些規律,首先得有數據啊,數據從哪裡來?就是從一個涵蓋所有已經解析三維結構的蛋白質-小分子復合物的資料庫裡面下載。這時候,手動一個個去下顯然是不可取的,我們需要寫個腳本,能從特定的網站選擇性得批量下載需要的信息。python是不錯的選擇。
import urllib #python中用於獲取網站的模塊
import urllib2, cookielib
有些網站訪問時需要cookie的,python處理cookie代碼如下:
cj = ***.cookiejar ( )
opener = ***.build_opener( ***.httpcookieprocessor(cj) )
***.install_opener (opener)
通常我們需要在網站中搜索得到我們需要的信息,這里分為二種情況:
1. 第一種,直接改變網址就可以得到你想要搜索的頁面:
def GetWebPage( x ): #我們定義一個獲取頁面的函數,x 是用於呈遞你在頁面中搜索的內容的參數
url = 'http://xxxxx/***.cgi?&' + 『你想要搜索的參數』 # 結合自己頁面情況適當修改
page = ***.urlopen(url)
pageContent = ***.read( )
return pageContent #返回的是HTML格式的頁面信息
2.第二種,你需要用到post方法,將你搜索的內容放在postdata裡面,然後返回你需要的頁面
def GetWebPage( x ): #我們定義一個獲取頁面的函數,x 是用於呈遞你在頁面中搜索的內容的參數
url = 'http://xxxxx/xxx' #這個網址是你進入搜索界面的網址
postData = ***.urlencode( { 各種『post』參數輸入 } ) #這裡面的post參數輸入需要自己去查
req= ***.request (url, postData)
pageContent = ***.urlopen (req). read( )
return pageContent #返回的是HTML格式的頁面信息
在獲取了我們需要的網頁信息之後,我們需要從獲得的網頁中進一步獲取我們需要的信息,這里我推薦使用 BeautifulSoup 這個模塊, python自帶的沒有,可以自行網路谷歌下載安裝。 BeautifulSoup 翻譯就是『美味的湯』,你需要做的是從一鍋湯裡面找到你喜歡吃的東西。
import re # 正則表達式,用於匹配字元
from bs4 import BeautifulSoup # 導入BeautifulSoup 模塊
soup = BeautifulSoup(pageContent) #pageContent就是上面我們搜索得到的頁面
soup就是 HTML 中所有的標簽(tag)BeautifulSoup處理格式化後的字元串,一個標準的tag形式為:
hwkobe24
通過一些過濾方法,我們可以從soup中獲取我們需要的信息:
(1) find_all ( name , attrs , recursive , text , **kwargs)
這裡面,我們通過添加對標簽的約束來獲取需要的標簽列表, 比如 ***.find_all ('p') 就是尋找名字為『p』的 標簽,而***.find_all (class = "tittle") 就是找到所有class屬性為"tittle" 的標簽,以及***.find_all ( class = ***.compile('lass')) 表示 class屬性中包含『lass』的所有標簽,這里用到了正則表達式(可以自己學習一下,非常有用滴)
當我們獲取了所有想要標簽的列表之後,遍歷這個列表,再獲取標簽中你需要的內容,通常我們需要標簽中的文字部分,也就是網頁中顯示出來的文字,代碼如下:
tagList = ***.find_all (class="tittle") #如果標簽比較復雜,可以用多個過濾條件使過濾更加嚴格
for tag in tagList:
print ***.text
***.write ( str(***.text) ) #將這些信息寫入本地文件中以後使用
(2)find( name , attrs , recursive , text , **kwargs )
它與 find_all( ) 方法唯一的區別是 find_all() 方法的返回結果是值包含一個元素的列表,而 find() 方法直接返回結果
(3)find_parents( ) find_parent( )
find_all() 和 find() 只搜索當前節點的所有子節點,孫子節點等. find_parents() 和 find_parent() 用來搜索當前節點的父輩節點,搜索方法與普通tag的搜索方法相同,搜索文檔搜索文檔包含的內容
(4)find_next_siblings() find_next_sibling()
這2個方法通過 .next_siblings 屬性對當 tag 的所有後面解析的兄弟 tag 節點進代, find_next_siblings() 方法返回所有符合條件的後面的兄弟節點,find_next_sibling() 只返回符合條件的後面的第一個tag節點
(5)find_previous_siblings() find_previous_sibling()
這2個方法通過 .previous_siblings 屬性對當前 tag 的前面解析的兄弟 tag 節點進行迭代, find_previous_siblings()方法返回所有符合條件的前面的兄弟節點, find_previous_sibling() 方法返回第一個符合條件的前面的兄弟節點
(6)find_all_next() find_next()
這2個方法通過 .next_elements 屬性對當前 tag 的之後的 tag 和字元串進行迭代, find_all_next() 方法返回所有符合條件的節點, find_next() 方法返回第一個符合條件的節點
(7)find_all_previous() 和 find_previous()
這2個方法通過 .previous_elements 屬性對當前節點前面的 tag 和字元串進行迭代, find_all_previous() 方法返回所有符合條件的節點, find_previous()方法返回第一個符合條件的節點
具體的使用方法還有很多,用到這里你應該可以解決大部分問題了,如果要更深入了解可以參考官方的使用說明哈!
③ 用python爬取關鍵詞並解釋
Copyright © 1999-2020, CSDN.NET, All Rights Reserved
python
打開APP
小羊努力搞代碼
關注
學習日誌:Python 實現網路爬蟲——提取關鍵字 原創
2022-06-19 13:02:38
小羊努力搞代碼
碼齡174天
關注
編寫一段Python代碼,向網路提交查詢關鍵詞「桃花源記」,抓取網路的查詢結果,要求有文字、鏈接,可以在瀏覽器中打開抓取的鏈接,或者調用瀏覽器打開抓取的鏈接。
紅框內是根據網站信息需要更改的內容。.png
附上完整代碼:
import json
import requests
from lxml import etree
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/88.0.4324.104 Safari/537.36"
}
response = requests.get('https://www..com/s?wd=桃花源記&lm=0', headers=headers)
r = response.text
html = etree.HTML(r, etree.HTMLParser())
r1 = html.xpath('//h3')
r2 = html.xpath('//*[@class="content-right_8Zs40"]')
r3 = html.xpath('//*[@class="c-row source_1Vdff OP_LOG_LINK c-gap-top-xsmall"]/a/@href')
for i in range(4):
r11 = r1[i].xpath('string(.)')
r22 = r2[i].xpath('string(.)')
r33 = r3[i]
with open('桃花源記.txt', 'a', encoding='utf-8') as c:
c.write(json.mps(r11,ensure_ascii=False) + '\n')
c.write(json.mps(r22, ensure_ascii=False) + '\n')
c.write(json.mps(r33, ensure_ascii=False) + '\n')
print(r11, end='\n')
print('------------------------')
print(r22, end='\n')
print(r33)
④ python中如何通過關鍵字查找到指定的HTML標簽
可以使用正則表達式的方法
正則表達式:工作職責:</th>s+<td>(.+?)</td>
importre
content="頁面內容"
re_1=re.search('工作職責:</th>s+<td>(.+?)</td>',content)
ifre_1:
printre_1.group(1)
else:
print"notfind!"
因為正則表達式有中文 所以要保證你的內容與文本是一個編碼
⑤ 如何用產品id索引爬取標簽內的產品各項標題鏈接價格 python
產品id索引爬取標簽內的產品各項標題鏈接價格 python可以使用網頁請求方式:最常見的方式,一般用於獲取或者查詢資源信息,也是大多數網站使用的方式,響應速度快,或者多以表單形式上傳參數,因此除了查詢信息外,還可以修改信息。
另外可以以開發者的身份進入網站進行價格查詢,打開網頁,用開發者模式,任意復制一條首條新聞標題,粘貼到搜索框里。開發者模式,依次點擊『network』,『XHR』找到翻譯數據,點擊Headers,請求為get方式,使用Beautiful soup解析網頁,然後再安裝bs。
Beautiful soup 指定xlml解析器進行解析,soup=BeautifulSoup(strhtml.text,'lxml'使用select(選擇器)定位數據,使用瀏覽器的開發者模式,將滑鼠停留在對應數據位置並右擊。
開發者界面會有被選中部分,右擊 ---> selector; 將路徑粘貼在文檔中,代碼如下#main > div > div.mtop.firstMod.clearfix > div.centerBox > ul.newsList > li:nth-child(1) > a。
這是選中的第一條路徑,但我們要獲取所有的新聞頭條,因此將:li:nth-child(1)中冒號(包含冒號)後面的刪掉。如下:#main > div > div.mtop.firstMod.clearfix > div.centerBox > ul.newsList > li > a,然後就可以直接查詢了。
⑥ python3 用BeautifulSoup 爬取指定ul下的a標簽
用select('ul的css路徑').find_all(...)
css路徑直接用瀏覽器開發視圖,從ul復制就好,當然也可以把前面多餘的部分刪掉
⑦ 如何用python 寫一個爬蟲用來爬P 站特定標簽下的高贊作品
Python寫這些爬蟲,批量獲取還是挺簡單的……不長逛P站但是寫了個可以獲取知乎指定收藏夾下的高贊答案的東西……
獲取知乎指定收藏夾下的高贊答案
獲取P站特定標簽下的高贊作品
這兩個需求應該是差不多的……
爬取收藏夾的代碼大概是這樣:
__author__ = '7sDream'
import hu
collection = hu.Collection('')
for answer in collection.answers:
if answer.upvote >= 1000:
answer.save(path=collection.name)
結果是這樣:
理論上來說爬P站應該差不多……
做好cookies管理,HTML解析就差不多了。
如果Python會的差不多了看看這個知乎模塊的源碼應該能寫出來P站的
⑧ Python爬蟲怎麼循環截取html標簽中間的內容
如果是中間的數據直接就用bs4最簡單
from bs4 import BeautifulSoup
#這里是請求過來的額數據處理,提取標簽
html = BeautifulSoup(response.text, 'html.parser')
body = html.body # 獲取body部分數據
div = body.find("div",{'id','today'}) #用find去找div標簽,id叫 today的標簽裡面的數據
就可以了
如果要提取標簽內容比如value的值
div = body.find("input",id='hidden_title')['value']
⑨ python爬蟲,用find_all()找到某一標簽後,怎麼獲取下面數個同名子標簽的內容
#!/usr/bin/envpython
#coding:utf-8
frombs4importBeautifulSoup
#這個data可以替換成你的div=soup.find_all('div',class_="star")
#取的時候記得循環處理
data='''
<div>
<spanclass='a'protype='d'>1</span>
<spanclass='a'protype='d'>2</span>
<spanclass='a'protype='d'>3</span>
<spanclass='a'protype='d'>4</span>
</div>
'''
soup=BeautifulSoup(data,'lxml')
spans=soup.find_all('span')
span_content=[]
foriinspans:
printi,i.text#這里取標簽span的內容
span_content.append(i.text)
printspan_content
------------------------
<spanclass="a"protype="d">1</span>1
<spanclass="a"protype="d">2</span>2
<spanclass="a"protype="d">3</span>3
<spanclass="a"protype="d">4</span>4
[u'1',u'2',u'3',u'4']
⑩ 如何用Python爬取出HTML指定標簽內的文本
你好!
可以通過lxml來獲取指定標簽的內容。
#安裝lxml
pipinstalllxml
importrequests
fromlxmlimporthtml
defgetHTMLText(url):
....
etree=html.etree
root=etree.HTML(getHTMLText(url))
#這里得到一個表格內tr的集合
trArr=root.xpath("//div[@class='news-text']/table/tbody/tr");
#循環顯示tr裡面的內容
fortrintrArr:
rank=tr.xpath("./td[1]/text()")[0]
name=tr.xpath("./td[2]/div/text()")[0]
prov=tr.xpath("./td[3]/text()")[0]
strLen=22-len(name.encode('GBK'))+len(name)
print('排名:{:<3},學校名稱:{:<{}} ,省份:{}'.format(rank,name,strLen,prov))
希望對你有幫助!