爬蟲學習

爬蟲學習

1、 第一隻爬蟲:

import requests
r = requests.get(
"http://www.baidu.com")

# HTTP請求的返回狀態,200表示連接成功,404表示失敗
print(r.status_code)

# # r的類型,屬於Response
# print(type(r))
#
# #
請求的頭部部分
# print(r.headers)


# HTTP
響應內容的字符串形式,即,url對應的頁面內容
#
基本會出現亂碼
print(r.text)

# HTTP header中猜測的響應內容的編碼方式
print(r.encoding)

# 從內容中分析出的響應內容編碼方式(備選編碼方式)
print(r.apparent_encoding)

# 解決亂碼問題
r.encoding = "utf-8"
print(r.text)

# HTTP響應內容的二進制形式
print(r.content)

 

 

爬蟲基本框架:

import requests


def getHTMLText(url):
   
try:
       
r = requests.get(url, timeout=30)
       
r.raise_for_status()  # 如果狀態不是200,引發HTTPEroor異常
       
r.encoding = r.apparent_encoding
       
return r.text
   
except:
       
return "產生異常"


if __name__ == "__main__"# TODO 有點不懂
   
url = "http://www.baidu.com"
   
print(getHTMLText(url))

 

 

 

 

 

robots協議:

查看方式:http://*****.com/robots.txt

 

 

爬取京東華爲手機信息:

1、簡潔版

import requests
r = requests.get(
"https://item.jd.com/4203985.html")

# 檢查訪問是否正常
print(r.status_code)

# 由頭部檢查網頁編碼方式
print(r.encoding)
# 提取text裏邊從01000的字符信息
print(r.text[:1000])

 

2、     安全版

import requests
url =
"https://item.jd.com/4203985.html"
try:

   
r = requests.get(url)
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    print(r.text[:1000])
except:
   
print("爬取失敗!")

 

 

 

爬取亞馬遜:(模擬瀏覽器,向網站發起請求)

說明:針對不對爬蟲開放的網站進行爬取

 

1、  簡潔版:

import requests

"""解決辦法,修改User-Agent爲一個瀏覽器字段
Mozilla/5.0
是一個標準瀏覽器字段(被多種瀏覽器採用)
"""
kv = {"user-agent": "Mozilla/5.0"}
url =
"https://www.amazon.cn/dp/B01M8L5Z3Y/ref=sr_1_1?s=books&ie=UTF8"\
     
"&qid=1519982182&sr=1-1&keywords=%E6%9E%81%E7%AE%80"

# headers 方法修改。。。請求信息
r = requests.get(url, headers=kv)
print(r.encoding)                         # url頭部爲utf-8格式
print(r.status_code)
# 'user-agent': 'Mozilla/5.0'  表明修改成功
print(r.request.headers)
print(r.text[:1000])

 

 

2、  安全版

 

import requests
url =
"https://www.amazon.cn/dp/B01M8L5Z3Y/ref=sr_1_1?s=books&ie=UTF8"\
     
"&qid=1519982182&sr=1-1&keywords=%E6%9E%81%E7%AE%80"
try:
   
kv = {"user-agent": "Mozilla/5.0"}
   
r = requests.get(url, headers=kv)
   
r.raise_for_status()
    r.encoding = r.apparent_encoding
    print(r.text[:1000])
except:
   
print("爬取失敗!")

 

 

百度360搜索關鍵字提交:

說明:使用360搜索時,把wd修改爲q就行了,其他都一樣

 

1、  簡潔版

 

import requests
kv = {
"wd": "python"}
r = requests.get(
"http://baidu.com/s", params=kv)
# 訪問狀態
print(r.status_code)

# 發給百度的url實際上是什麼
print(r.request.url)

 

2、  安全版

 

import requests
keyword =
"python"
try:
   
kv = {"wd":keyword}
   
r = requests.get("http://baidu.com/s", params=kv)
   
print(r.request.url)
   
r.raise_for_status()
    # 顯示爬取的文本長度
   
print(len(r.text))
except:
   
print("爬取失敗!")

 

爬取國家地理圖片:

1、  簡潔版

 

import requests
path =
"D:/abc.jpg"
url = "http://img0.dili360.com/rw9/ga/M00/02/AB/wKgBzFQ26i2AWujSAA_-xvEYLbU441.jpg"
r = requests.get(url)
print(r.status_code)
# print(r.text)

#
打開一個文件,並把它定義爲一個文件標誌符f
with open(path, "wb") as f:
   
# r.content表示返回內容的二進制形式,再使用write把他寫出了
   
f.write(r.content)
 
  f.close()

 

2、  安全版

 

import requests
import os  # TODO 不會
url = "http://img0.dili360.com/rw9/ga/M00/48/4E/wKgBzFllve2AO9VBAEzNdvr41Hs146.tub.jpg"
# 定義一個根目錄
root = "D://pics//"
# 定義本地路徑的文件名稱,而且與網絡文件名最後一部分相同
path = root +url.split("/")[-1# TODO 不會
try:
   
# 如果根目錄不存在,就建立一個這樣的目錄
   
if not os.path.exists(root):
       
os.mkdir(root)
    # 判斷文件存不存在,如果文件不存在就從網上獲取這樣一個文件
   
if not os.path.exists(path):
       
r = requests.get(url)
        with open(path, "wb") as f:
           
f.write(r.content)
            f.close()
            print("文件保存成功!")
   
else:
       
print("文件已經存在!")
except:
   
print("爬取失敗!")

 

 

IP地址歸屬地自動查詢:

1、  簡潔版

 

import requests
kv = {
"user-agent": "Mozilla/5.0"}
url =
"http://m.ip138.com/ip.asp?ip="
r = requests.get(url + "202.204.80.112")
r = requests.get(url
, headers=kv)
print(r.status_code)
print(r.request.headers)
r.encoding = r.apparent_encoding
print(r.text[-500:])

 

2、  安全版

 

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

 

 

beautifulsoup庫安裝:

import requests
r = requests.get(
"https://python123.io/ws/demo.html")
print(r.text)
demo = r.text

# 導入beautiful
from bs4 import BeautifulSoup
# demo進行解析(使用html.parse解釋器進行解析)
soup = BeautifulSoup(demo, "html.parser")
print(soup.prettify())

 

 

信息提取:

說明:提取網站源碼中的網址鏈接

# 提取HTML中所有的url鏈接
import requests
from bs4 import BeautifulSoup

r = requests.get(
"https://python123.io/ws/demo.html")
demo = r.text
soup = BeautifulSoup(demo
, "html.parser")
for link in soup.find_all("a"):
   
print(link.get("href"))

 

 

基於bs4庫的HTML內容查找方法:                        

 

import requests
from bs4 import BeautifulSoup

r = requests.get(
"https://python123.io/ws/demo.html")
demo = r.text
soup = BeautifulSoup(demo
, "html.parser")

"""BeautifulSoup庫提供了一個方法,如下(查找信息)
<>.find_all(name, attrs, recursive, string, **kwargs)
返回一個列表類型,儲存查找的結果

name
:對標籤名稱的檢索字符串
attrs:
對標籤屬性值的檢索字符串,可標註屬性檢索
recursive:
是否對某一個標籤子孫所有節點進行搜索,默認是True(是一個布爾類型的值)
string
:對<>..</>中的字符串區域的檢索字符串

"""

"""   
name方法     """
# # 查找a 標籤內容
# print(soup.find_all("a"))
# #
查找a b 兩個標籤內容
# print(soup.find_all(["a", "b"]))
#
# #
查看有多少個標籤(tag
# for tag in soup.find_all(True):
#     
print(tag.name)
#
# print("")
# """若只顯示以b開頭的標籤(tag,
#
這裏需要正則表達式庫
# """
# #
導入正則表達式庫
# import re
# for tag in soup.find_all(re.compile("b")):
#    
print(tag.name)

"""    attrs 方法     """
# # 輸出一個帶有course屬性值的標籤
# print(soup.find_all("p", "course"))
# print("")
#
# #
查找某個屬性值=**,作爲查找依據(查找必須十分精確,不然返回空列表)
# print(soup.find_all(id="link1"))
# print("")
#
# """
針對根據屬性查找必須十分精確,解決措施(導入正則表達式)
#
進行比較模糊的查找
# """
# import re
# print(soup.find_all(id=re.compile("link"))) 
# 查找內容明顯比上面多

"""    recursive方法   """
# print(soup.find_all("a"))
# #
檢查a 標籤下的子節點沒有內容,返回空列表[]
# print(soup.find_all("a", recursive=False))

"""   string   """
# print(soup)  # 查看一下soup完整信息
# print("")
# #
同樣查找依據必須十分精確(輸入的字符串必須精確)
# print(soup.find_all(string="Basic Python"))
# print("")
# #
同樣如果引入正則表達式,就可以進行模糊檢索soup裏的內容
# import re
# print(soup.find_all(string=re.compile("python")))

中國大學排名定向爬蟲:

程序結構設計:

步驟一: 從網絡上獲取大學排名網頁內容

步驟二:提取網頁內容中的有用信息並把他放到合適的數據結構中

步驟三:利用數據結構展示並輸出結果

 

import requests
from bs4 import BeautifulSoup
import bs4

"""獲取url信息,輸出url內容"""
def getHTMLText(url):
   
try:
       
r = requests.get(url, timeout=30)
       
r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
   
except:
       
return ""

"""
將這一個頁面放到ulist"""
def fillUnivList(ulist, html):
   
# 解析HTML
   
soup =BeautifulSoup(html, "html.parser")
   
# 解析htmltbody所在位置,在tbody標籤中找到每一所大學對應的tr標籤
   
for tr in soup.find("tbody").children:

       
# tr標籤中找到其中td標籤的信息,並把需要的標籤加到列表中
       
# isinstancebs4庫中方法,篩選tr中有標籤的信息(排除沒有標籤的信息)
       
if isinstance(tr, bs4.element.Tag):
           
tds = tr("td")
           
ulist.append([tds[0].string, tds[1].string, tds[2].string])

"""ulist信息打印出來"""
def printUnivList(ulist, num):
   
# 打印表頭
   
print("{:^10}\t{:^6}\t{:^10}".format("排名", "學校名稱", "總分"))
   
for i in range(num):
       
u = ulist[i]
        print("{:^10}\t{:^6}\t{:^10}".format(u[0], u[1], u[2]))


# 主函數
def main():
   
uinfo = []
    url = "http://zuihaodaxue.cn/shengyuanzhiliangpaiming2018.html"
   
html =getHTMLText(url)
   
fillUnivList(uinfo, html)
   
printUnivList(uinfo, 20# 獲取20所學校排名


main()

 

Beautiful Soup庫:

bs類基本元素:

Tag:標籤,基本信息組織單元,分別用<>和</> 標明開頭和結尾

Name:標籤的名字,<>…</p>的名字是’p’ ,格式:<tag>.name

Attributes:標籤屬性,字典形式組織,格式<tag>.attrs

NavigableString: 標籤內非屬性字符串,<>…</>中字符串,格式:<tag>.string

Comment:標籤內部字符串的註釋部分,一種特殊的Comment類型

 

from bs4 import BeautifulSoup
import requests
r = requests.get(
"https://python123.io/ws/demo.html")
print(r.text)
print("")
demo = r.text
soup = BeautifulSoup(demo
, "html.parser")
print(soup.title)  # 打印title標籤
print("")

# # a 標籤
# tag = soup.a
# print(tag)

# #
獲取a 標籤名字、a父親的名字(p)、a爺爺標籤的名字(body)
# print(soup.a.name)
# print(soup.a.parent.name)
# print(soup.a.parent.parent.name)

#
標籤中非屬性字符串,NavigableString: 標籤內非屬性字符串,<>…</>中字符串,格式:<tag>.string

# comment
註釋
newsoup = BeautifulSoup()

 

 

基於bs4庫的HTML內容遍歷方法:

from bs4 import BeautifulSoup
import requests
r = requests.get(
"https://python123.io/ws/demo.html")
# print(r.text)
print("")
demo = r.text
soup = BeautifulSoup(demo
, "html.parser")


"""標籤樹的下行遍歷:.contents指將標籤所有子節點存入列表
   
.children指用於循環遍歷兒子節點
   
.descendants 子孫節點的迭代類型,包含所有子孫節點,用於遍歷
"""
# # .contents用法
#
# # head
標籤、以及他的兒子節點
# print(soup.head)
# print("")
# print(soup.head.contents) 
# 兒子節點
# #
查看body 標籤兒子的信息
# print(soup.body.contents)
# print(len(soup.body.contents)) 
# 獲取body 標籤兒子的數量(5個)
# print(soup.body.contents[1]) 
# 獲取body 標籤兒子節點的第二個

# # .children
用法
# for child in soup.body.children:
#    
print(child)

# # .descendants用法
# for child in soup.body.descendants:
#    
print(child)

"""標籤樹的上行遍歷
.parent
節點的父親標籤
.parents
節點的先輩(包含父親及其以上)標籤的迭代類型,用於循環遍歷先輩節點
"""

# # parent用法
# print(soup.title.parent) 
# title的父親是head標籤
# print("")
# print(soup.html.parent) 
#html 標籤是最高級的標籤類型,他的父親就是自己
# print("")
# print(soup.parent) 
# soup本身就是一種特殊標籤,他的父親是空的

# #
標籤樹的上行遍歷
# for parent in soup.a.parents:
#    
print(parent)
# else:
#     print(parent.name)

"""標籤樹的平行遍歷(只能發生在同一個父親節點下的各節點間)
.next_sibling:
返回按照HTML文本順序的下一個平行節點標籤
.previous_sibling:
返回。。。上一個。。
.next_siblings:
迭代類型,返回按照HTML文本順序的後續所有平行節點標籤
.previous_siblings:
迭代類型,。。。前續。。。
"""
# print(soup.a.next_sibling)  # 標籤可以是字符串
# print(soup.a.next_sibling.next_sibling) 
# a的下下個標籤
# print(soup.a.previous_sibling) 
# a的上一個標籤
# print(soup.a.previous_sibling.previous_sibling) 
# a的上上一個標籤
# #
標籤樹的遍歷
# for sibling in soup.a.next_siblings: 
#遍歷後續節點
#    
print(sibling)
# for sibling in soup.a.previous_siblings: # 遍歷前續節點
#    
print(sibling)

 

 

 

 

基於bs4庫的HTML格式化:

from bs4 import BeautifulSoup
import requests
r = requests.get(
"https://python123.io/ws/demo.html")
# print(r.text)
print("")
demo = r.text
soup = BeautifulSoup(demo
, "html.parser")

# soup.prettify() 用於給標籤增加換行符,使輸出內容更清晰(即格式化)
print(soup.prettify())
print("")
print(soup.a.prettify())

 

HTML:

HTML是www(World Wide Web)的信息組織方式

 

正則表達式:(regular expression    .re)

變化最大的是年齡說明:正則表達式是用來簡潔表達一組字符串的表達式

不把勞動作爲第一生產力優勢:簡潔,可以簡單地表達很大一個字符串的特徵

 

 

re庫基本使用:

"""
re
庫的函數用法:一次性使用
解釋:pattern:正則表達式的字符串或原生字符串表示
    
string:待匹配字符串
    
flags:正則表達式使用時的控制標記
    
maxsplit:最大分割數,剩餘部分作爲最後一個元素輸出
    
repl:替換匹配字符串的字符串
    
count:匹配的最大次數

re.search()  
在一個字符串中搜索匹配正則表達式的第一個位置,返回match對象
格式:re.search(pattern,string, flags=0)
re.match()  
在一個字符串的開始位置起匹配正則表達式,返回match對象
格式:re.match(pattern,string, flags=0)
re.findall()  
搜索字符串,以列表類型返回全部能匹配的子串
格式:re.findall(pattern,string, flags=0)
re.split() 
 將一個字符串按照正則表達式匹配結果進行分割,返回列表類型
格式:re.findall(pattern,string, maxsplit=0, flags=0)
re.finditer()  
搜索字符串,返回匹配結果的迭代類型,每個迭代元素是match對象
re.finditer(pattern, string, flags=0)
re.sub()  
在一個字符串中替換所有匹配正則表達式的子串,返回替換後的字符串
re.finditer(pattern, repl, string, count=0, flags=0)
"""

# # search函數
# import re
# match = re.search(r"[1-9]\d{5}", "BLT 100081")
# if match:
#    
print(match.group(0))

# # match函數
# import re
# match = re.match(r"[1-9]\d{5}", "BLT 100081")
# if match:
#    
# 匹配結果是空,無法輸出結果
#    
print(match.group(0))
# print("")
# match = re.match(r"[1-9]\d{5}", "100081 BLT")
# if match:
#     # 正常輸出
#    
print(match.group(0))

# # findall函數
# import re
# ls = re.findall(r"[1-9]\d{5}", "BLT100081 TSU100084")
# #
返回一個列表
# print(ls)

# # split
函數
# import re
# #
輸出不匹配的字符串部分
# print(re.split(r"[1-9]\d{5}", "BLT100081 TSU100084"))
# #
只匹配第一個
# print(re.split(r"[1-9]\d{5}", "BLT100081 TSU100084",maxsplit=1))

# # finditer
函數
# import re
# for m in re.finditer(r"[1-9]\d{5}", "BLT100081TSU100084"):
#    
if m:
#         print(m.group(0))

# sub函數
import re
print(re.sub(r"[1-9]\d{5}", ":zipcode", "BLT100081 TSU100084"))





"""
re
庫的面向對象用法(先編譯):多次使用,方法   regex = re.compile(pattern, flags=0)
regex(正則表達式)
pattern
表示正則表達式的字符串或原生字符串,flags表示正則表達式使用時的控制標記
re
庫的等價用法:(方法同上)
regex.search():
regex.match():
regex.findall():
regex.split():
regex.finditer():
regex.sub():
"""

 

 

淘寶商品價格爬取:

import re
import requests


# 獲得頁面
def getHTMLText(url):
   
try:
       
r = requests.get(url, timeout=30)
       
r.raise_for_status()  # 如果狀態不是200,引發HTTPEroor異常
       
r.encoding =r.apparent_encoding
       
return r.text
   
except:
       
return ""


# 解析頁面,獲取商品名稱、價格
def parsePage(ilt, html):
   
try:
       
plt = re.findall(r'\"view_price\"\:\"[\d\.]*\"', html)  # TODO 爲什麼把高亮的斜槓 \ 去掉,程序還可以運行
       
tlt = re.findall(r'\"raw_title\"\:\".*?\"', html)
       
for i in range(len(plt)):
           
# eval函數可以將獲取的字符串的雙引號或單引號去掉
           
# spilt函數使用:分割字符串,獲得鍵值對的後半部分
           
price = eval(plt[i].split(':')[1])
           
title = eval(tlt[i].split(':')[1])
           
ilt.append([price, title])
   
except:
       
print("")


# 將商品信息輸出在屏幕上
def printGoodList(ilt):
   
# tplt 是打印模板
   
tplt = "{:4}\t{:8}\t{:16}"
   
# 打印表頭
   
print(tplt.format("序號", "價格", "商品名稱"))
   
count = 0
   
for g in ilt:
       
count = count + 1
       
print(tplt.format(count, g[0], g[1]))


# 定義主函數,記錄程序運行整個過程
def main():
   
goods = "墨水"
   
# 爬取第一頁和第二頁,所以深度設爲2
   
depth = 2
   
start_url = "http://s.taobao.com/search?q="+ goods
   
# 對輸出變量定義一個變量
   
infoList = []
   
# 遍歷頁面信息,單獨訪問並處理每個頁面
   
for i in range(depth):
       
# 使用try 對過程中發生的錯誤進行異常判斷
       
try:
           
url = start_url + "&s="+ str(44*i)
           
html = getHTMLText(url)
            parsePage(infoList, html)
       
except:
           
continue
   
printGoodList(infoList)


main()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章