Python 3 Anaconda 下爬蟲學習與爬蟲實踐 (1)


 

 

 

環境python 3

anaconda

pip

以及各種庫

1.requests庫的使用

主要是如何獲得一個網頁信息

重點是

r=requests.get("https://www.google.com/?hl=zh_CN")
這里是爬取了谷歌主頁(科學上網)可以換成其他頁面爬取
import requests
r=requests.get("https://www.google.com/?hl=zh_CN")
print(r.status_code)
r.encoding='utf-8'
print(r.text)

  這里是代碼部分,requests.get獲得了一個網頁的信息,存入r中

這個時候使用r.status_code如果返回200則證明調用成功,404表示失敗,其實不是200就是失敗

r.text是響應內容的字符串形式

r.encoding是從http header中猜測的響應內容編碼方式(如果header中不存在charset,則認為編碼方式為ISO-8859-1,這個時候就需要改為備選編碼中的編碼形式)

r.apparent_encoding 是從內容中分析出的響應內容編碼方式(其實較為准確)

r.content 相應內容的二進制形式(比如獲取圖像時使用)

異常處理

r.raise_for_status() 如果不是200,產生異常requests.HTTPError

加入異常處理后形成了一個爬取網頁的通用代碼框架(使得爬取更穩定)

 

如下:

import requests

def getHTMLText(url):
    try:
        r=requests.get(url,timeout=30)
        r.raise_for_status()
        r.encoding=r.apparent_encoding
        return r.text
    except:
        return "產生異常"

if __name__=="__main__":
    url="http://www.baidu.com/"
    print(getHTMLText(url))

為理解這個庫,需要理解HTTP

HTTP:Hypertext Transfer Protocol,超文本傳輸協議

HTTP對數據的操作與request庫是對應的

通過URL獲得資源

head方法可以通過較少的流量獲得大概信息

requests.request(method,url,**kwargs)  最后一個參數可以省略

最常使用的還是get和head,主要是get

 

關於爬蟲的量級

1.小規模,數據量小,爬取速度不敏感,爬取網頁,玩轉網頁為目的的 這個時候使用requests庫就可以滿足

2.中規模,數據規模較大,爬取速度敏感,爬取網站,爬取系列網站 Scrapy庫

3.爬取全網,大規模,搜索引擎比如百度,google,爬取速度關鍵,這一類的爬蟲是定制開發的而非第三方庫

 

下面是實踐部分,有一些網站有反爬機制,比如亞馬遜,所以需要改動我們的user-agent進行偽裝,代碼如下:

import requests

def getHTMLText(url):
    try:
        # 更改頭部信息,模擬成一個瀏覽器
        kv = {'user-agent': 'Mozilla/5.0'}
        r=requests.get(url,headers=kv,timeout=30)
        r.raise_for_status()
        r.encoding=r.apparent_encoding
        print(r.request.headers)

        return r.text[:1000]
    except:
        return "產生異常"

if __name__=="__main__":
    url="https://www.amazon.cn/dp/B07FDT8P6C/ref=cngwdyfloorv2_recs_0?pf_rd_p=d2aa3428-dc2b-4cfe-bca6-5e3a33f2342e&pf_rd_s=desktop-2&pf_rd_t=36701&pf_rd_i=desktop&pf_rd_m=A1AJ19PSB66TGU&pf_rd_r=G32Y9X81496BTATWRG3A&pf_rd_r=G32Y9X81496BTATWRG3A&pf_rd_p=d2aa3428-dc2b-4cfe-bca6-5e3a33f2342e"
    print(getHTMLText(url))

 包含搜索的百度爬蟲代碼,期中kv_word是提交的輸入關鍵詞,最終返回獲得的信息數量,每次略有差別,我隨便一次為319295:

import requests

def getHTMLText(url):
    try:
        # 更改頭部信息,模擬成一個瀏覽器
        kv_head = {'user-agent': 'Mozilla/5.0'}
        kv_word={'wd':'Python'}
        r=requests.get(url,params=kv_word,headers=kv_head,timeout=30)
        r.raise_for_status()
        r.encoding=r.apparent_encoding
        print(r.request.url)

        return len(r.text)
    except:
        return "產生異常"

if __name__=="__main__":
    url='https://www.baidu.com/s'
    print(getHTMLText(url))

下面嘗試爬取圖片,主要就是用r.content轉換為二進制進行存取代碼如下:

import requests

def getHTMLText(url):
    try:
        path='F:/a/abc.jpeg'
        # 更改頭部信息,模擬成一個瀏覽器
        kv_head = {'user-agent': 'Mozilla/5.0'}
        r=requests.get(url,headers=kv_head,timeout=30)
        print(r.status_code)
        #將獲得的存入路徑中,r.content是二進制文件
        with open(path,'wb') as f:
            f.write(r.content)
        f.close()
        return len(r.text)
    except:
        return "產生異常"

if __name__=="__main__":
    url='https://b-ssl.duitang.com/uploads/item/201601/25/20160125170559_SPKF2.jpeg'
    print(getHTMLText(url))

下面我們嘗試通過ip138網站來提交ip相關信息,爬取ip地址所在地,

可以先手動提交一個,發現其特點:

http://www.ip138.com/ips138.asp?ip=10.3.8.211

所以我們就可以仿真這個來進行查詢

下面是代碼部分:

import requests
url='http://www.ip138.com/ips138.asp?ip='
try:
    r=requests.get(url+'10.3.8.211')
    r.raise_for_status()
    r.encoding=r.apparent_encoding
    print(r.text[-500:])
except:
    print("爬取失敗")

這個樣例主要是幫助學習怎么用改變url的方式模擬按鍵,輸入等等操作

要學會以URL的視角看待網絡內容,也就是要以爬蟲的視角來看待網絡內容

 

下面就進入了解析的學習

這里需要用到的庫是beautiful soup

簡單來說主要是兩行代碼

from bs4 import BeautifulSoup
soup=BeautifulSoup('<p>data</p>',"html.parser")

就可以解析我們看到的信息

<p>...</p>    標簽Tag

現在學習獲取a標簽也就是鏈接標簽的內容的寫法,這個時候主要就是寫tag=soup.a

代碼為:

import requests
from bs4 import BeautifulSoup

r=requests.get("https://www.baidu.com/")
demo=r.text
soup=BeautifulSoup(demo,"html.parser")
tag=soup.a
print(tag)

執行結果為:

<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>

標簽被打印出來,如果文件中有多個a標簽就只會返回第一個

如果相知道上一層是什么標簽可以使用

soup.a.parent.name

 就可以獲得其上一層標簽的名字,這里接着上一個代碼寫,所以上一層獲得的返回結果為dev

下面學習怎么獲得不同屬性的值,通過

print(tag.attrs)

 可以知道有哪些屬性,比如我們需要獲得class屬性的值,那么使用tag.attrs['class']

剛剛幾步實驗的代碼如下:

import requests
from bs4 import BeautifulSoup

r=requests.get("https://www.baidu.com/")
demo=r.text
soup=BeautifulSoup(demo,"html.parser")
tag=soup.a
print(tag.attrs)
print(tag.attrs['class'])
print(tag)

那么我們怎么可以獲得中間文本的值(也就是標簽內非屬性字符串)呢,這個時候就要用到

soup.a.string

標簽之間的關系如下圖:

以及一些其他的對於標簽的處理函數,如下代碼:

import requests
from bs4 import BeautifulSoup

r=requests.get("https://scholar.google.com/citations?hl=en&user=NoVsmbcAAAAJ")
demo=r.text
soup=BeautifulSoup(demo,"html.parser")
tag=soup.tbody
print(tag)
print(tag.contents)#找到里面內容
print(len(tag.contents))#內容長度
print(tag.contents[1])#取其中的第二個數據
for child in tag.children:  #遍歷兒子節點
    print(child)
#print(tag.attrs['class'])
#print(soup.a.string)

同理.parent返回父標簽,  .parents返回祖先標簽

以及還有一些平行標簽  

print(tag.next_sibiling)

 通過這些知識,我們可以對前后標簽進行遍歷

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM