国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Python_爬蟲基礎(chǔ)

ixlei / 2762人閱讀

摘要:并不是所有爬蟲都遵守,一般只有大型搜索引擎爬蟲才會遵守。的端口號為的端口號為工作原理網(wǎng)絡(luò)爬蟲抓取過程可以理解為模擬瀏覽器操作的過程。表示服務(wù)器成功接收請求并已完成整個處理過程。

爬蟲概念

數(shù)據(jù)獲取的方式:

企業(yè)生產(chǎn)的用戶數(shù)據(jù):大型互聯(lián)網(wǎng)公司有海量用戶,所以他們積累數(shù)據(jù)有天然優(yōu)勢。有數(shù)據(jù)意識的中小型企業(yè),也開始積累的數(shù)據(jù)。

數(shù)據(jù)管理咨詢公司

政府/機構(gòu)提供的公開數(shù)據(jù)

第三方數(shù)據(jù)平臺購買數(shù)據(jù)

爬蟲爬取數(shù)據(jù)

什么是爬蟲

抓去網(wǎng)頁數(shù)據(jù)的程序

網(wǎng)頁三大特征:

每個網(wǎng)頁都有自己的URL

網(wǎng)頁都使用HTML標記語言來描述頁面信息

網(wǎng)頁都使用HTTP/HTTPS協(xié)議來傳輸HTML數(shù)據(jù)

爬蟲的設(shè)計思路

確定需要爬取的網(wǎng)頁URL地址

通過HTTP/HTTPS協(xié)議來獲取對應(yīng)的HTML頁面

提取HTML頁面中的數(shù)據(jù)
如果是需要的數(shù)據(jù),就保存起來
如果頁面是其它URL,那就繼續(xù)爬取

如何抓取HTML頁面
HTTP協(xié)議請求的處理,urllib, urllib2, requests,處理后的請求可以模擬瀏覽器發(fā)送請求,獲取服務(wù)器響應(yīng)的文件

解析服務(wù)器響應(yīng)的內(nèi)容
re, xpath(常用), BeautifulSoup4(bs4), jsonpath, pyquery等使用某種描述性一樣來給需要提取的數(shù)據(jù)定義一個匹配規(guī)則,符合這個規(guī)則的數(shù)據(jù)就會被匹配。

如何采集動態(tài)HTML,驗證碼的處理
Selenium(自動化測試工具) + PhantomJS(無界面瀏覽器)
驗證碼處理通過Tesseract: 機器圖像識別系統(tǒng)(圖片中的文本識別)

Scrapy框架
(Scrapy, Pyspider)

高性能高定制型(異步網(wǎng)絡(luò)框架twisted),所以數(shù)據(jù)下載速度快

提供了數(shù)據(jù)存儲,數(shù)據(jù)下載,提取規(guī)則等組件

分布式策略

是否有那么多的機器去做分布式?

獲取的數(shù)據(jù)是否值得搭建分布式系統(tǒng)?

使用scrapy-redis來搭建,在Scrapy的基礎(chǔ)上添加了一套 Redis數(shù)據(jù)庫為核心的一套組件,讓Scrapy框架支持分布式的功能。主要在Redis中做請求指紋去重請求分配數(shù)據(jù)臨時存儲

爬蟲 - 反爬蟲 - 反反爬蟲

反爬蟲: User-Agent, IP, 代理, 驗證碼, 動態(tài)數(shù)據(jù)加載, 加密數(shù)據(jù)
數(shù)據(jù)的價值,是否值得去費勁去做反爬蟲,一般做到代理階段或封IP
機器成本 + 人力成本 > 數(shù)據(jù)價值

爬蟲和反爬蟲之間的斗爭,最后一定是爬蟲獲勝。
只要是真實用戶可以瀏覽的網(wǎng)頁數(shù)據(jù),爬蟲就一定能爬下來。(爬蟲模擬瀏覽器獲取數(shù)據(jù))

爬蟲集合awesome-spider

通用爬蟲

搜索引擎使用的爬蟲系統(tǒng)

目標:盡可能把互聯(lián)網(wǎng)上所有的網(wǎng)頁下載下來,放到本地服務(wù)器里形成備份,再對這些網(wǎng)頁做相關(guān)處理(提取關(guān)鍵字,去掉廣告),最后提供一個用戶檢索接口

抓取流程:

首先選取一部分已有的URL,把這些URL放到待爬取隊列。

從隊列里去取出這些URL,然后解析DNS得到主機IP,然后去這個IP對應(yīng)的服務(wù)器下載HTML頁面,保存到搜索引擎的本地服務(wù)器里,之后把這個已經(jīng)爬過的URL放入到已經(jīng)爬取隊列中

分析網(wǎng)頁內(nèi)容,找出網(wǎng)頁中的其它URL內(nèi)容,繼續(xù)爬取。

搜索引擎如何獲取一個新網(wǎng)站的URL:

主動向搜索引擎提交網(wǎng)址: 百度搜索資源平臺

在其它網(wǎng)站設(shè)置外鏈

搜索引擎會和DNS服務(wù)商進行合作,可以快速收錄新的網(wǎng)站

通用爬蟲并不是萬物皆可爬,它也需要遵守規(guī)則:
Robots協(xié)議,協(xié)議會指明通用爬蟲可以爬取網(wǎng)頁的權(quán)限。
Robots.txt并不是所有爬蟲都遵守,一般只有大型搜索引擎爬蟲才會遵守。

通用爬蟲工作流程:
爬取網(wǎng)頁 -> 存儲數(shù)據(jù) -> 內(nèi)容處理 -> 提供檢索/排名服務(wù)

搜索引擎排名:

PageRank值:根據(jù)網(wǎng)站的流量(pv),流量越高,排名約靠前

競價排名

通用爬蟲的缺點:

只能提供和文本相關(guān)的內(nèi)容(HTML,Word,PDF)等,但是不能提供多媒體(音樂,視頻,圖片)和二進制文件。

提供的結(jié)果千篇一律,不能針對不同領(lǐng)域的人提供不同的搜索結(jié)果。

不能理解人類語義上的檢索。

DNS: 把域名解析成IP

聚焦爬蟲

爬蟲程序員寫的針對某種內(nèi)容爬蟲。(針對通用爬蟲的缺點)

面向主題爬蟲,面向需求爬蟲,會針對某種特定的內(nèi)容去爬取信息,而且會保證內(nèi)容信息和需求盡可能相關(guān)。

HTTP&HTTPS

HTTP協(xié)議(HyperText Transfer Protocol,超文本傳輸協(xié)議):是一種發(fā)布和接收HTML頁面的方法。

HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)簡單講是HTTP的安全版,在HTTP下加入SSL

SSL(Secure Sockets Layer 安全套接層)主要用于Web的安全傳輸協(xié)議,在傳輸層對網(wǎng)絡(luò)連接進行加密,保障在Internet上數(shù)據(jù)傳輸?shù)陌踩?/p>

HTTP的端口號為80

HTTPS的端口號為443

HTTP工作原理

網(wǎng)絡(luò)爬蟲抓取過程可以理解為模擬瀏覽器操作的過程

瀏覽器的主要功能是向服務(wù)器發(fā)出請求,在瀏覽器窗口中展示您選擇的網(wǎng)絡(luò)資源,HTTP是一套計算機通過網(wǎng)絡(luò)進行通信的規(guī)則。

常用的請求報頭:

Host (主機和端口號): 對應(yīng)網(wǎng)址URL中的Web名稱和端口號,用于指定被請求資源的Internet主機和端口號,通常屬于URL的一部分。

Connection (鏈接類型): 表示客戶端與服務(wù)連接類型

Client 發(fā)起一個包含 Connection:keep-alive 的請求,HTTP/1.1使用 keep-alive 為默認值。

Server收到請求后:如果 Server 支持 keep-alive,回復(fù)一個包含 Connection:keep-alive 的響應(yīng),不關(guān)閉連接; 如果 Server 不支持keep-alive,回復(fù)一個包含 Connection:close 的響應(yīng),關(guān)閉連接。

如果client收到包含 Connection:keep-alive 的響應(yīng),向同一個連接發(fā)送下一個請求,直到一方主動關(guān)閉連接。

keep-alive在很多情況下能夠重用連接,減少資源消耗,縮短響應(yīng)時間,比如當(dāng)瀏覽器需要多個文件時(比如一個HTML文件和相關(guān)的圖形文件),不需要每次都去請求建立連接。

Upgrade-Insecure-Requests (升級為HTTPS請求): 升級不安全的請求,意思是會在加載 http 資源時自動替換成 https 請求,讓瀏覽器不再顯示https頁面中的http請求警報。(HTTPS 是以安全為目標的 HTTP 通道,所以在 HTTPS 承載的頁面上不允許出現(xiàn) HTTP 請求,一旦出現(xiàn)就是提示或報錯。)

User-Agent (瀏覽器名稱): 是客戶瀏覽器的名稱

Accept (傳輸文件類型): 指瀏覽器或其他客戶端可以接受的MIME(Multipurpose Internet Mail Extensions(多用途互聯(lián)網(wǎng)郵件擴展))文件類型,服務(wù)器可以根據(jù)它判斷并返回適當(dāng)?shù)奈募袷健?/p>

Accept: */*:表示什么都可以接收。

Accept:image/gif:表明客戶端希望接受GIF圖像格式的資源;

Accept:text/html:表明客戶端希望接受html文本。

Accept: text/html, application/xhtml+xml;q=0.9, image/*;q=0.8:表示瀏覽器支持的 MIME 類型分別是 html文本、xhtml和xml文檔、所有的圖像格式資源。html中文件類型的accept屬性有哪些

Referer (頁面跳轉(zhuǎn)處): 表明產(chǎn)生請求的網(wǎng)頁來自于哪個URL,用戶是從該 Referer頁面訪問到當(dāng)前請求的頁面。這個屬性可以用來跟蹤Web請求來自哪個頁面,是從什么網(wǎng)站來的等。有時候遇到下載某網(wǎng)站圖片,需要對應(yīng)的referer,否則無法下載圖片,那是因為人家做了防盜鏈,原理就是根據(jù)referer去判斷是否是本網(wǎng)站的地址,如果不是,則拒絕,如果是,就可以下載;

Accept-Encoding(文件編解碼格式): 指出瀏覽器可以接受的編碼方式。編碼方式不同于文件格式,它是為了壓縮文件并加速文件傳遞速度。瀏覽器在接收到Web響應(yīng)之后先解碼,然后再檢查文件格式,許多情形下這可以減少大量的下載時間。例如:Accept-Encoding:gzip;q=1.0, identity; q=0.5, *;q=0

Accept-Language(語言種類): 指出瀏覽器可以接受的語言種類,如en或en-us指英語,zh或者zh-cn指中文,當(dāng)服務(wù)器能夠提供一種以上的語言版本時要用到。

Accept-Charset(字符編碼): 指出瀏覽器可以接受的字符編碼。例如:Accept-Charset:iso-8859-1,gb2312,utf-8

Cookie (Cookie): 瀏覽器用這個屬性向服務(wù)器發(fā)送Cookie。Cookie是在瀏覽器中寄存的小型數(shù)據(jù)體,它可以記載和服務(wù)器相關(guān)的用戶信息,也可以用來實現(xiàn)會話功能

Content-Type (POST數(shù)據(jù)類型): POST請求里用來表示的內(nèi)容類型。例如:Content-Type = Text/XML; charset=gb2312:

常用的響應(yīng)報頭(了解):

Cache-Control:must-revalidate, no-cache, private: 告訴客戶端,服務(wù)端不希望客戶端緩存資源,在下次請求資源時,必須要從新請求服務(wù)器,不能從緩存副本中獲取資源。

Connection:keep-alive: 客戶端服務(wù)器的tcp連接也是一個長連接,客戶端可以繼續(xù)使用這個tcp連接發(fā)送http請求

Content-Encoding:gzip: 告訴客戶端,服務(wù)端發(fā)送的資源是采用gzip編碼的,客戶端看到這個信息后,應(yīng)該采用gzip對資源進行解碼。

Content-Type:text/html;charset=UTF-8: 告訴客戶端,資源文件的類型,還有字符編碼,客戶端通過utf-8對資源進行解碼,然后對資源進行html解析。

Date:Sun, 21 Sep 2016 06:18:21 GMT: 服務(wù)端發(fā)送資源時的服務(wù)器時間,GMT是格林尼治所在地的標準時間。http協(xié)議中發(fā)送的時間都是GMT的,這主要是解決在互聯(lián)網(wǎng)上,不同時區(qū)在相互請求資源的時候,時間混亂問題。

Expires:Sun, 1 Jan 2000 01:00:00 GMT: 這個響應(yīng)頭也是跟緩存有關(guān)的,告訴客戶端在這個時間前,可以直接訪問緩存副本,很顯然這個值會存在問題,因為客戶端和服務(wù)器的時間不一定會都是相同的,如果時間不同就會導(dǎo)致問題。所以這個響應(yīng)頭是沒有Cache-Control:max-age=*這個響應(yīng)頭準確的,因為max-age=date中的date是個相對時間.

Pragma:no-cache: 這個含義與Cache-Control等同。

Server:Tengine/1.4.6: 這個是服務(wù)器和相對應(yīng)的版本,只是告訴客戶端服務(wù)器的信息。

Transfer-Encoding:chunked: 這個響應(yīng)頭告訴客戶端,服務(wù)器發(fā)送的資源的方式是分塊發(fā)送的。

響應(yīng)狀態(tài)碼:

100~199:表示服務(wù)器成功接收部分請求,要求客戶端繼續(xù)提交其余請求才能完成整個處理過程。

200~299:表示服務(wù)器成功接收請求并已完成整個處理過程。常用200(OK 請求成功)。

300~399:為完成請求,客戶需進一步細化請求。例如:請求的資源已經(jīng)移動一個新地址、常用302(所請求的頁面已經(jīng)臨時轉(zhuǎn)移至新的url)、307和304(使用緩存資源)。

400~499:客戶端的請求有錯誤,常用404(服務(wù)器無法找到被請求的頁面)、403(服務(wù)器拒絕訪問,權(quán)限不夠)。

500~599:服務(wù)器端出現(xiàn)錯誤,常用500(請求未完成。服務(wù)器遇到不可預(yù)知的情況)。

Cookie 和 Session:
因為服務(wù)器和客戶端的交互僅限于請求/響應(yīng)過程,結(jié)束之后便斷開,在下一次請求時,服務(wù)器會認為新的客戶端。為了維護他們之間的鏈接,讓服務(wù)器知道這是前一個用戶發(fā)送的請求,必須在一個地方保存客戶端的信息

Cookie:通過在客戶端 記錄的信息確定用戶的身份。
Session:通過在服務(wù)器端 記錄的信息確定用戶的身份。

urllib

urllib.request

linux中的py源碼文件位置:
python自帶:vim /usr/lib/python2.7/urllib2.py
pip安裝:vim /usr/local/lib/python3.6/site-packages/django/http/cookie.py

urllib2.urlopen
# -*- coding:utf-8 -*-

import urllib.request as urllib2

# 返回類文件對象
response = urllib2.urlopen("http://www.baidu.com/")
# urlopen不支持構(gòu)造

# 服務(wù)器返回類文件對象支持python文件對象的操作方法
# read()方法就是讀取文件里面的全部內(nèi)容,返回字符串
html = response.read()

print(html)
Request
# -*- coding:utf-8 -*-

import urllib.request as urllib2


ua_headres = {
    "User_Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Mobile Safari/537.36"
}

# urllib2.Request(url, data, headres)
# 通過urllib2.Request()方法構(gòu)造一個請求對象
requset = urllib2.Request("http://www.baidu.com", headers=ua_headres)


# 返回類文件對象, urlopen不支持構(gòu)造
response = urllib2.urlopen(requset)

# 服務(wù)器返回類文件對象支持python文件對象的操作方法
# read()方法就是讀取文件里面的全部內(nèi)容,返回字符串
html = response.read()

print(html)

User_Agent,是發(fā)送請求必須帶的請求頭

Response響應(yīng)

response是服務(wù)器響應(yīng)的類文件,除了支持文件操作的方法外,常用的方法也有:
respnse.getcode(), response.geturl(), response.info()

#condig=utf-8

import urllib.request as urllib2

# print(dir(urllib2))

ua_headres = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.4620.400 QQBrowser/9.7.13014.400"        
}

request = urllib2.Request("http://www.baidu.com/", headers=ua_headres)

response = urllib2.urlopen(request)

html = response.read()

# 返回HTTP的響應(yīng)碼,成功返回200
# 4 服務(wù)器頁面出錯, 5 服務(wù)器問題
print(response.getcode())

# 返回實際數(shù)據(jù)的url,防止重定向問題
print(response.geturl())

# 返回服務(wù)器響應(yīng)報頭信息
print(response.info())

# print(dir(response))
User-Agent歷史

如果用一個合法的身份去請求別人網(wǎng)站,就是歡迎的,所以就應(yīng)該給這個代碼加上一個身份,就是所謂的User-Agent頭。

urllib2默認的User-Agent頭為:Python-urllib/x.yxyPython主版本和次版本號,例如 Python-urllib/2.7

Mosaic世界上第一個瀏覽器:美國國家計算機應(yīng)用中心
Netscape,網(wǎng)景:Netscape(支持框架)
Microsoft微軟:Internet Explorer

第一次瀏覽器大戰(zhàn):網(wǎng)景公司失敗

Mozilla 基金組織:Firefox 火狐 內(nèi)核(Gecko內(nèi)核)(瀏覽器支持內(nèi)核開始,User-Agent開始逐漸使用)

User-Agent 決定用戶的瀏覽器,為了獲取更好的HTML頁面效果

IE就給自己披著了個Mozilla的外皮

內(nèi)核:

Mozilla: Firefox (Gecko)

IE: Trident

Opera: Presto

Linux: KHTML (like Gecko)

Apple: Webkit (like KTML)

Google: Chrome (like webkit)

add_header() & get_header()

add_header(): 添加/修改 一個HTTP報頭
get_header(): 獲取一個已有的HTTP報頭值,只能第一個字母大寫,其它的必須小寫

# -*- coding:utf-8 -*-

import urllib.request as urllib2
import random

url = "http://www.baidu.com/"

# 可以是User-Agent列表,也可以是代理列表。 作用:反反爬蟲
ua_list = [
    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36",
    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50"
]

# 在User-Agent列表里隨機選擇一個User-Agent
user_agent = random.choice(ua_list)

# 構(gòu)造一個請求
request = urllib2.Request(url)

# add_header()方法,添加/修改 一個HTTP報頭
request.add_header("User-Agent", user_agent)

# get_header() 獲取一個已有的HTTP報頭值,只能第一個字母大寫,其它的必須小寫
request.get_header("User-agent")

response = urllib2.urlopen(request)

html = response.read()
print(html)
urllib.urlencode

編碼:
urlencode位置:urllib.parse.urlencode(values)。 其中values所需要編碼的數(shù)據(jù),參數(shù)只能為字典
解碼:
unquote: urllib.parse.unquote(values)

#conding=utf-8

import urllib.parse

test = {
    "test": "我的"
}

# 通過urllib.urlencode()方法,將字典鍵值對按URL編碼轉(zhuǎn)換,從而能被web服務(wù)器接受。
enCodeTest = urllib.parse.urlencode(test)

# 冒號解析為等號
print(enCodeTest) # test=%E6%88%91%E7%9A%84

# 通過urllib.unquote()方法,把 URL編碼字符串,轉(zhuǎn)換回原先字符串。
print(urllib.parse.unquote(enCodeTest)) # test=我的
爬取百度貼吧起始頁到結(jié)束頁的案例
#conding=utf-8

import urllib.request
import urllib.parse

def loadPage(url, filename):
    """
        作用: 根據(jù)url發(fā)送請求,獲取服務(wù)器響應(yīng)文件
        url: 需要爬取的url地址
        filename: 處理的文件名
    """
    print("正在下載" + filename)
    headers = {
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"
    }
    request = urllib.request.Request(url, headers=headers)
    return urllib.request.urlopen(request).read()
    

def writePage(html, filenmae):
    """
        作用:將html內(nèi)容寫入到本地
        html: 服務(wù)器響應(yīng)文件內(nèi)容
    """
    print("正在保存" + filenmae)
    # 文件寫入
    with open(filenmae, "w") as f: #  with 之后,不需要做文件關(guān)閉還有其它上下文處理的操作 等同于 open(), write(), close()
        f.write(html.decode("utf-8"))
    print("-" * 30)    
    print("thanks")


def tiebaSpider(url, beginPage, endPage):
    """
        作用: 貼吧爬蟲調(diào)度器,負責(zé)組合處理
        url: 貼吧url的前部分
        beginPage: 起始頁
        endPage: 結(jié)束頁
    """
    for page in range(beginPage, endPage+1):
        pn = (page - 1) * 50
        filename = "第" + str(page) + "頁.html"
        fullurl = url + "&pn=" + str(pn)
        # print(fullurl)
        html = loadPage(fullurl, filename)
        writePage(html, filename)
        # print(html)

if __name__ == "__main__":
    kw = input("請輸入需要爬取的貼吧名:")
    beginPage = int(input("請輸入起始頁:"))
    endPage = int(input("請輸入結(jié)束頁:"))
    
    # https://tieba.baidu.com/f?ie=utf-8&kw=javascirpt&fr=search
    url = "https://tieba.baidu.com/f?"
    key = urllib.parse.urlencode({"kw": kw})
    fullurl = url + key

    tiebaSpider(fullurl, beginPage, endPage)
POST請求的模擬

GetPost請求的區(qū)別:

Get請求:查詢參數(shù)在QueryString里保存

Post請求:查詢參數(shù)在FormData中保存

Post請求:

# -*- coding:utf-8 -*-

import urllib.request
import urllib.parse

url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"

key = input("請輸入查詢翻譯的文字:")

# 發(fā)送到服務(wù)器的表單數(shù)據(jù),如果是中文需要轉(zhuǎn)碼
fromdata = {
    "i": key,
    "from": "AUTO",
    "to": "AUTO",
    "smartresult": "dict",
    "client": "fanyideskweb",
    "salt": "1528127663128",
    "sign": "c060b56b628f82259225f751c12da59a",
    "doctype": "json",
    "version": "2.1",
    "keyfrom": "fanyi.web",
    "action": "FY_BY_REALTIME",
    "typoResult": "false"
}

data = urllib.parse.urlencode(fromdata).encode("utf-8")

headers = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"
}

request = urllib.request.Request(url, data=data, headers=headers)

html = urllib.request.urlopen(request).read().decode()

print(html)
獲取AJAX加載的內(nèi)容

AJAX一般返回的是JSON,直接對AJAX地址進行postget,就返回JSON數(shù)據(jù)了。

“作為一名爬蟲工程師,最需要關(guān)注的是數(shù)據(jù)的來源”

# -*- coding:utf-8 -*-

import urllib.request
import urllib.parse


url = "https://movie.douban.com/j/search_subjects?"
headers = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"
}
formdata = {
    "type": "movie",
    "tag": "熱門",
    "sort": "recommend",
    "page_limit": 20,
    "page_start": 40
}

data = urllib.parse.urlencode(formdata).encode("utf-8")
request = urllib.request.Request(url, data=data, headers=headers)
html = urllib.request.urlopen(request).read().decode()

print(html)
處理HTTPS請求 SSL證書驗證

網(wǎng)站的SSL證書是經(jīng)過CA認證的,則能夠正常訪問
多帶帶處理SSL證書,讓程序忽略SSL證書驗證錯誤

# -*- coding:utf-8 -*-

import urllib.request
import ssl

# 表示忽略未經(jīng)核實的SSL證書認證
context = ssl._create_unverified_context()

url = "https://www.12306.cn/mormhweb/"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"
}

request = urllib.request.Request(url, headers = headers)

# 在urlopen()方法里 指明添加 context 參數(shù)
response = urllib.request.urlopen(request, context = context)

print(response.read())

CA: 數(shù)字證書認證中心的簡稱,是指發(fā)放、管理、廢除數(shù)字證書的受信任的第三方機構(gòu)(類似與身份證)
CA的作用: 檢查證書持有者身份的合法性,并簽發(fā)證書,以防證書被偽造或篡改,以及對證書和密鑰進行管理

一般正常的網(wǎng)站都會主動出示自己的數(shù)字證書,來確保客戶端和網(wǎng)站服務(wù)器之間的通信數(shù)據(jù)是加密安全的.

Handler和Opener的使用

自定義Handler

# -*- coding:utf-8 -*-

import urllib.request

# 構(gòu)建一個HTTPHandler處理器對象,支持處理HTTP的請求
# http_hander = urllib.request.HTTPHandler()
http_hander = urllib.request.HTTPHandler(debuglevel=1)

# 調(diào)用build_opener()方法構(gòu)建一個自定義的opener對象,參數(shù)是構(gòu)建的處理器對象
opener = urllib.request.build_opener(http_hander)

req = urllib.request.Request("http://www.baidu.com")

res = opener.open(req)

print(res.read().decode())
開放代理和私密代理

高匿:無法拿到真正的物理ip,只能獲取代理服務(wù)器ip
透明:能看到代理服務(wù)器ip,也可以看到物理ip地址
快代理
西刺免費代理

使用代理IP,這是爬蟲/反爬蟲的第二大招,通常也是最好用的。
很多網(wǎng)站會檢測某一段時間某個IP的訪問次數(shù)(通過流量統(tǒng)計,系統(tǒng)日志等),如果訪問次數(shù)多的不像正常人,它會禁止這個IP的訪問。
可以設(shè)置一些代理服務(wù)器,每隔一段時間換一個代理,就算IP被禁止,依然可以換個IP繼續(xù)爬取。

# -*- coding:utf-8 -*-

import urllib.request


# 代理開關(guān),是否啟用代理
proxyswitch = True

# 公開代理
proxy_ip = {
  "http": "123.57.217.208:3128"
}

# 私密代理 授權(quán)的賬號密碼
# proxy_ip_auth = {
#   "http": "user:passwd@ip:prot"
# }

# 構(gòu)建一個handler對象,參數(shù)是一個字典類型,包括代理類型和代理服務(wù)器ip+prot
http_proxy_handler = urllib.request.ProxyHandler(proxy_ip)

# 構(gòu)建一個沒有代理對象的處理器對象
null_proxy_headler = urllib.request.ProxyHandler({})


if proxyswitch:
  opener = urllib.request.build_opener(http_proxy_handler)
else:
  opener = urllib.request.build_opener(null_proxy_headler)

# 構(gòu)建一個全局的opener,之后的所有請求都可以用urlopen()方式發(fā)送,也附帶Handler功能
urllib.request.install_opener(opener)
request = urllib.request.Request("http://www.baidu.com/")
response = urllib.request.urlopen(request)

# response = opener.open(request)

print(response.read().decode())

ProxyBasicAuthHandler(代理授權(quán)驗證):

#conding=utf-8

import urllib.request


user = ""
passwd = ""
proxyserver = ""

# 構(gòu)建一個密碼管理對象,用來保存需要處理的用戶名和密碼
passwdmgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()

# 添加賬戶信息,第一個參數(shù)realm是與遠程服務(wù)器相關(guān)的域信息,一般都是寫None,后面三個參數(shù)分別是 代理服務(wù)器、用戶名、密碼
passwdmgr.add_password(None, proxyserver, user, passwd)

# 構(gòu)建一個代理基礎(chǔ)用戶名/密碼驗證的ProxyBasicAuthHandler處理器對象,參數(shù)是創(chuàng)建的密碼管理對象
proxy_auth_handler = urllib.request.ProxyDigestAuthHandler(passwdmgr)

# 通過 build_opener()方法使用這些代理Handler對象,創(chuàng)建自定義opener對象,參數(shù)包括構(gòu)建的 proxy_handler 和 proxyauth_handler
opener = urllib.request.build_opener(proxy_auth_handler)

request = urllib.request.Request("http://www.baidu.com/")
response = opener.open(request)

print(response.read().decode())
Cookie

Cookie 是指某些網(wǎng)站服務(wù)器為了辨別用戶身份和進行Session跟蹤,而儲存在用戶瀏覽器上的文本文件,Cookie可以保持登錄信息到用戶下次與服務(wù)器的會話。

HTTP是無狀態(tài)的面向連接的協(xié)議, 為了保持連接狀態(tài), 引入了Cookie機制 Cookie是http消息頭中的一種屬性

Cookie名字(Name)
Cookie的值(Value)
Cookie的過期時間(Expires/Max-Age)
Cookie作用路徑(Path)
Cookie所在域名(Domain),
使用Cookie進行安全連接(Secure)。

前兩個參數(shù)是Cookie應(yīng)用的必要條件,另外,還包括Cookie大小(Size,不同瀏覽器對Cookie個數(shù)及大小限制是有差異的)。

Cookie由變量名和值組成,根據(jù) Netscape公司的規(guī)定,Cookie格式如下:

Set-Cookie: NAME=VALUE;Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE

Python處理Cookie,一般是通過cookielib模塊和urllib2模塊的HTTPCookieProcessor處理器類一起使用。

cookielib模塊:主要作用是提供用于存儲cookie的對象

HTTPCookieProcessor處理器:主要作用是處理這些cookie對象,并構(gòu)建handler對象。

cookielib 庫

該模塊主要的對象有CookieJarFileCookieJarMozillaCookieJarLWPCookieJar

一般情況下,只用CookieJar(),如果需要和本地文件交互,就需要使用MozillaCookjar()LWPCookieJar()

獲取Cookie,并保存到CookieJar()對象中:

#!/usr/local/bin/python

import urllib.request
import http.cookiejar

cookiejar = http.cookiejar.CookieJar()

http_handler = urllib.request.HTTPCookieProcessor(cookiejar)

opener = urllib.request.build_opener(http_handler)

opener.open("http://www.baidu.com")

cook_str = ""
for item in cookiejar:
    cook_str = cook_str + item.name + "=" + item.value + ";"

print(cook_str[:-1])

# BAIDUID=5DB0FC0C0DC9692BB8EE6EDC93A2EDEA:FG=1;BIDUPSID=5DB0FC0C0DC9692BB8EE6EDC93A2EDEA;H_PS_PSSID=1468_26259_21099_26350_26580;PSTM=1528615563;BDSVRTM=0;BD_HOME=0

訪問網(wǎng)站獲得cookie,并把獲得的cookie保存在cookie文件中:

#!/usr/local/bin/python

import http.cookiejar
import urllib.request

filename = "cookie.txt"

# 聲明一個MozillaCookieJar(有save實現(xiàn))對象實例來保存cookie,之后寫入文件
cookiejar = http.cookiejar.MozillaCookieJar(filename)

handler = urllib.request.HTTPCookieProcessor(cookiejar)
opener = urllib.request.build_opener(handler)
req = opener.open("http://www.baidu.com")

# 保存cookie到本地文件
cookiejar.save()

print(1)
非結(jié)構(gòu)化數(shù)據(jù)和結(jié)構(gòu)化數(shù)據(jù)

實際上爬蟲一共就四個主要步驟:

明確目標 (要知道準備在哪個范圍或者網(wǎng)站去搜索)

爬 (將所有的網(wǎng)站的內(nèi)容全部爬下來)

取 (去掉對沒用處的數(shù)據(jù))

處理數(shù)據(jù)(按照想要的方式存儲和使用)

re模塊
pattern = re.compile(regExp)

pattern.match(): 從起始位置開始查找,返回第一個符合規(guī)則的,只匹配一次。
pattern.search(): 從任意位置開始查找,返回第一個符合規(guī)則的,只匹配一次。
pattern.findall(): 所有的全部匹配,返回列表
pattern.split(): 分割字符串,返回列表
pattern.sub(): 替換
rs.I 忽略大小寫
re.S 全文匹配

match(str, begin, end):

>>> pattern = re.compile(r"([a-z]+) ([a-z]+)", re.I)
>>> m = pattern.match("hello world hello python")
>>> m.group()
"hello world"
>>> m.group(1)
"hello"
>>> m.group(2)
"world"

findall(str, begin, end):

>>> pattern = re.compile(r"d+")
>>> pattern.findall("hello world 123 456 789")
["123", "456", "789"]
>>> 

split(str, count):

>>> pattern = re.compile(r"[sd;]+")
>>> pattern.split("a ba;m; a  ")
["a", "bx07", "m", "a", ""]
>>> 
>>> pattern = re.compile("[sd;]+")
>>> pattern.split(r"a ba;m; a  ")
["a", "ba", "m", "a", ""]
>>> 

sub():

>>> pattern = re.compile(r"(w+)(w+)")
>>> strs = "hello 123, world 456"
>>> pattern.sub("hello world", strs)
"hello world hello world, hello world hello world"
>>>
xpath

chrome插件:XPath Helper
XPath (XML Path Language) 是一門在 XML 文檔中查找信息的語言,可用來在XML文檔中對元素和屬性進行遍歷。

lxml庫:
lxml是 一個HTML/XML的解析器,主要的功能是如何解析和提取HTML/XML數(shù)據(jù)。

獲取屬性:@src, @title, @class
獲取內(nèi)容: /text()
模糊查詢: contains(@id, "模糊字符串")

xpath匹配規(guī)則:

//div[@class="pic imgcover"]/img/@src

xpath模糊匹配:

//div[contains(@id, "qiushi_tag")]

獲取某個網(wǎng)站的圖片:

#conding=utf-8

import urllib.request
import urllib.parse
from lxml import etree # 我乃河北,姓氏顏良

class getQdailyImg:
    def __init__(self, url):
        self.url = url

    def loadPage(self):
        print("正在下載...")
        headres = {
            "User-Agent": "ie 的user-Agent"
        }
        req = urllib.request.Request(self.url, headers=headres)
        html = urllib.request.urlopen(req).read().decode()
        xmlDom = etree.HTML(html)
        linkList = xmlDom.xpath("http://div[@class="pic imgcover"]/img/@src")
        print(linkList)
        self.writePage(linkList)

    def writePage(self, data):
        for item in data:
            with open("img.txt", "w") as f:
                f.write(item)

if __name__ == "__main__":
    qdI = getQdailyImg("http://www.qdaily.com/")
    qdI.loadPage()

# -*- coding:utf-8 -*-

import urllib.request
import json
from lxml import etree

url = "http://www.qiushibaike.com/8hr/page/1"
headers = {
    "user-agent": "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB7.0)"
}

req = urllib.request.Request(url, headers=headers)
html = urllib.request.urlopen(req).read()
text = etree.HTML(html)

# 作為根目錄節(jié)點
node_list = text.xpath("http://div[contains(@id, "qiushi_tag")]")

items = {}
for node in node_list:
    username = node.xpath("./div[@class="author clearfix"]//h2/text()")[0]

    image = node.xpath(".//div[@class="thumb"]//@src")

    content = node.xpath(".//div[@class="content"]/span")[0].text

    zan = node.xpath(".//i")[0].text

    comment = node.xpath(".//i")[1].text

    items = {
        "username": username,
        "image": image,
        "content": content,
        "zan": zan,
        "comment": comment
    }

    with open("qiushi.json", "a") as f:
        f.write(json.dumps(items, ensure_ascii=False) + "
")

print("ok")
BeautifulSoup

Beautiful Soup也是一個HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML數(shù)據(jù)。

BeautifulSoup用來解析HTML比較簡單,API非常人性化,支持CSS選擇器、Python標準庫中的HTML解析器,也支持lxml的 XML解析器。

pip install bs4
beautifulsoup4文檔

tag: BeautifulSoup(html).div

attrs: BeautifulSoup(html).div.nameBeautifulSoup(html).div.attres

content: BeautifulSoup(html).span.string

#conding=utf-8

from bs4 import BeautifulSoup
import requests
import time

def captchaMethod(captcha_data):
    with open("captcha.jpg", "wb") as f:
        f.write(captcha_data)
    return input("請輸入驗證碼:")     

def getLoginZhihu():
    # 構(gòu)建Session對象,保存cookie值
    sess = requests.Session()

    headers = {
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36 QQBrowser/4.3.4986.400"
    }

    html = sess.post("https://www.zhihu.com/#sigin", headers=headers).text
    bs = BeautifulSoup(html, "lxml")
    _xsrf = bs.find("input", attrs={"name": "_xsrf"}).get("value")

    captcha_url = "https://www.zhihu.com/captcha.gif?r=%d&type=login" % (time.time() * 1000)
    captcha = sess.get(captcha_url, headers=headers).content

    # 獲取驗證碼文字
    text = captchaMethod(captcha)

    data = {
        "_xsrf": _xsrf,
        "email": "123636374@qq.com",
        "password": "ALARMCHIME",
        "captcha": text
    }
    # 登錄 獲取cookie
    res = sess.post("https://www.zhihu.com/login/email", data=data, headers=headers).text

    res = sess.get("https://www.zhihu.com/people/", headers)

if __name__ == "__main__":
    getLoginZhihu()
    
JSON和JSONPATH

JsonJsonPath應(yīng)用

json.loads(): 把Json格式字符串解碼轉(zhuǎn)換成Python對象

json.dumps(): 實現(xiàn)python類型轉(zhuǎn)化為json字符串,返回一個str對象 把一個Python對象編碼轉(zhuǎn)換成Json字符串

json.dump(): 將Python內(nèi)置類型序列化為json對象后寫入文件

json.load(): 讀取文件中json形式的字符串元素 轉(zhuǎn)化成python類型

dictStr = {"city": "北京", "name": "大貓"}
print(json.dumps(dictStr, ensure_ascii=False))
# {"city": "北京", "name": "大劉"}

listStr = [{"city": "北京"}, {"name": "大劉"}]
json.dump(listStr, open("listStr.json","w"), ensure_ascii=False)

strDict = json.load(open("dictStr.json"))
print(strDict)
# {u"city": u"u5317u4eac", u"name": u"u5927u5218"}

# -*- coding:utf-8 -*-

import json
import urllib.request
import jsonpath

headers = {
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36 QQBrowser/4.3.4986.400"
}
url = "https://www.lagou.com/lbs/getAllCitySearchLabels.json"

request = urllib.request.Request(url, headers=headers)

response = urllib.request.urlopen(request)
html = response.read().decode()

unicodeStr = json.loads(html)
content = jsonpath.jsonpath(unicodeStr, "$..name")
print(content)
array = json.dumps(content, ensure_ascii=False)

with open("lagoucontent.json", "w") as f:
    f.write(array)
多線程爬蟲

一個進程可能包括多個線程,線程之間執(zhí)行任務(wù),必須通過加鎖方式控制它們(阻塞)
父線程和子線程都關(guān)系,只要父線程執(zhí)行完,不管子線程如何,都一并結(jié)束

計算機的核心是CPU,CPU承擔(dān)了所有的計算任務(wù)

一個CPU核心一次只能執(zhí)行一個任務(wù)
多個CPU核心同時可以執(zhí)行多個任務(wù)

一個CPU一次只能執(zhí)行一個進程,其它進程處于非運行

進程里包含的執(zhí)行單元叫線程
一個進程 可以包含 多個線程

一個進程的內(nèi)存空間是共享的,每個進程里的線程都可以使用這個共享空間
一個線程在使用這個共享空間的時候,其它線程必須等待它結(jié)束

通過“鎖”實現(xiàn),作用就是防止多個線程使用當(dāng)前內(nèi)存空間。
先使用的線程會加鎖,鎖上該空間,其它線程就在等待。

進程:表示程序的一次執(zhí)行
線程:CPU運算的基本調(diào)度單位

GIL: Python里的執(zhí)行通行證,而且只有唯一個。拿到通行證的線程才會執(zhí)行

Python 的多線程適用于:大量密集的I/O處理 (多帶帶都任務(wù),一個進程,只能執(zhí)行一個任務(wù))
Python 的多進程適用于:大量的密集并行計算

#conding=utf-8

import json
import threading
from queue import Queue

import requests
from lxml import etree

CREAWL_EXIT = False
PARSE_EXIT = False

"""
    采集線程
"""
class ThreadCrawl(threading.Thread):
    def __init__(self, threadName, pageQueue, dataQueue):
        # threading.Thread.__init__(self)
        super(ThreadCrawl, self).__init__() # 多個父類,多重繼承
        self.threadName = threadName
        self.pageQueue = pageQueue
        self.dataQueue = dataQueue
        self.headers = {
            "user-agent": "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB7.0)"
        }

    def run(self):
        print("start" + self.threadName)
        while not CREAWL_EXIT:
            try:
                page = self.pageQueue.get(False)
                url = "https://www.qiushibaike.com/8hr/page/" + str(page) + "/"
                res = requests.get(url, headers=self.headers).text
                self.dataQueue.put(res)
            except:
                pass
        print("end" + self.threadName)      

"""
    解析線程
"""
class ThreadParse(threading.Thread):
    def __init__(self, threadingName, dataQueue, filename):
        super(ThreadParse, self).__init__()
        self.threadingName = threadingName
        self.dataQueue = dataQueue
        self.filename = filename

    def run(self):
        print("start" + self.threadingName)
        while not PARSE_EXIT:
            try:
                html = self.dataQueue.get(False)
                self.parse(html)
            except:
                pass
        print("end" + self.threadingName)


    def parse(self, html):
        text = etree.HTML(html)
        node_list = text.xpath("http://div[contains(@id, "qiushi_tag")]")
        items = {}
        for node in node_list:
            username = node.xpath("./div[@class="author clearfix"]//h2/text()")[0]
            image = node.xpath(".//div[@class="thumb"]//@src")
            content = node.xpath(".//div[@class="content"]/span")[0].text
            zan = node.xpath(".//i")[0].text
            comment = node.xpath(".//i")[1].text
            items = {
                "username": username,
                "image": image,
                "content": content,
                "zan": zan,
                "comment": comment
            }
            self.filename.write(json.dumps(items, ensure_ascii=False) + "
")


def main():
    # 頁碼
    pageQueue = Queue(10)
    # 放入1~10的數(shù)字
    for i in range(1, 10+1):
        pageQueue.put(i)

    # 采集結(jié)果(每頁的HTML源碼)
    dataQueue = Queue()

    filename = open("duanzi.json", "a")

    crawlList = ["采集線程1", "采集線程2", "采集線程3"]

    threadcrawl = []
    for threadName in crawlList:
        thread = ThreadCrawl(threadName, pageQueue, dataQueue)
        thread.start()
        threadcrawl.append(thread)
    
    parseList = ["解析線程1", "解析線程2", "解析線程3"]
    threadparse = []
    for threadName in parseList:
        thread = ThreadParse(threadName, dataQueue, filename)
        thread.start()
        threadparse.append(thread)
    
    # 等待pageQueue隊列為空, 或者 數(shù)據(jù)隊列為空,也就是等待之前執(zhí)行的操作執(zhí)行完畢
    while not pageQueue.empty() or not dataQueue.empty():
        pass

    global CREAWL_EXIT
    CREAWL_EXIT = True
    print("queue隊列為空")

    global PARSE_EXIT
    PARSE_EXIT = True
    print("data隊列為空")

    for threadItem in crawlList:
        threadItem.join("")
        print("1")

if __name__ == "__main__":
    main()

自動化測試unittest模塊使用和模擬用戶點擊抓取數(shù)據(jù)(拿去ajax分頁數(shù)據(jù))

# -*- coding:utf-8 -*-

import unittest
from selenium import webdriver
from bs4 import BeautifulSoup as bs

class Douyu(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.PhantomJS()

    # unittest測試方法必須有`test`字樣開頭
    def testDouyu(self):
        self.driver.get("https://www.douyu.com/directory/all")
        while True:
            soup = bs(self.driver.page_source, "lxml")
            names = soup.find_all("h3", {"class": "ellipsis"})
            viewNums = soup.find_all("span", {"class": "dy-num fr"})
            
            for name, viewNum in zip(names, viewNums):
                print("房間名" + name.get_text() + "; " + "觀眾人數(shù)" + viewNum.get_text())

            # 在頁面源碼中找到"下一頁"未隱藏的標簽,就退出循環(huán)
            if self.driver.page_source.find("shark-pager-disable-next") != -1:
                break

            # 一直點擊下一頁
            self.driver.find_element_by_class_name("shark-pager-next").click()    

    # 測試結(jié)束執(zhí)行的方法
    def tearDown(self):
        self.driver.quit()

if __name__ == "__main__":
    unittest.main()

執(zhí)行javascript語句:execute_script

#conding=utf-8

from selenium import webdriver
import time

driver = webdriver.PhantomJS("/Users/linxingzhang/Library/Python/3.6/lib/python/site-packages/selenium/webdriver/phantomjs")
driver.get("https://movie.douban.com/typerank?type_name=劇情&type=11&interval_id=100:90&action=")

time.sleep(3)
# 向下滾動10000像素
js = "document.body.scrollTop=10000"
# js="var q=document.documentElement.scrollTop=10000"

# 查看頁面快照
driver.save_screenshot("douban.png")

# 執(zhí)行JS語句
driver.execute_script(js)
time.sleep(10)

# 查看頁面快照
driver.save_screenshot("newdouban.png")

driver.quit()
投票
import datetime
import sys
import threading
import time
from random import choice  # choice() 方法返回一個列表,元組或字符串的隨機項

import requests
from lxml import etree

from fake_useragent import UserAgent  # 引入隨機的UA

# 設(shè)置user-agent列表,每次請求時,隨機挑選一個user-agent
ua_list = UserAgent()


def get_ip():
    """
        獲取代理ip
    """
    url = "http://www.xicidaili.com/nn"
    headers = {
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "Host": "www.xicidaili.com",
        "Referer": "http: // www.xicidaili.com/nn",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6726.400 QQBrowser/10.2.2265.400"
    }
    ret = requests.get(url, headers=headers)
    xmlDom = etree.HTML(ret.text)

    data = xmlDom.xpath("http://table[@id="ip_list"]//tr")
    z = []
    for tr in data:
        if tr.xpath("td"):
            ip = tr.xpath("td")[1].text  # 獲取所有IP
            port = tr.xpath("td")[2].text  # 獲取所有端口
            z.append(ip + ":" + port)
    return z


def get_url(url, code=0, ips=[]):
    """
        投票
        如果因為代理IP已失效造成投票失敗,則會自動換一個代理IP后繼續(xù)投票
    """
    try:
        ip = choice(ips)
        print(ip, "ip" * 5)
    except:
        return False
    else:
        proxies = {
            "http": ip
        }
        headers = {
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
            "Host": "best.zhaopin.com",
            "Origin": "https: // best.zhaopin.com",
            "Referer": "https//best.zhaopin.com/?sid=121128100&site=sou",
            "User-Agent": ua_list.random
        }
        print(ua_list.random, "ua_list" * 5)

    try:
        data = {"bestid": "3713", "score": "5,5,5,5,5,5", "source": "best"}
        # 跳過證書的驗證 verify=False
        result = requests.post(url, data=data, headers=headers, proxies=proxies)
        print(result, "result" * 5)
    except requests.exceptions.ConnectionError:
        print("ConnectionError")
        if not ips:
            print("ip 失效")
            sys.exit()

        # 刪除不可用的代理IP
        if ip in ips:
            ips.remove(ip)
        # 重新請求url
        get_url(url, code=0, ips=[])
    else:
        date = datetime.datetime.now().strftime("%H:%M:%S")
        # result.text() 投票成功顯示1  失敗顯示0
        print("第%s次 [%s] [%s]:投票%s (剩余可用代理IP數(shù):%s)" %
              (code, date, ip, result.text, len(ips)))


def main():
    url = "https://best.zhaopin.com/API/ScoreCompany.ashx"  # 投票的請求
    ips = []
    for i in range(6000):
        if i % 1000 == 0:
            ips.extend(get_ip())
            # print("-" * 100)
            # print(ips)
        t = threading.Thread(target=get_url, args=(url, i, ips))
        t.start()
        time.sleep(1)


if __name__ == "__main__":
    main()
Tesseract

機器識別中的文字識別

pip install pytesseract

識別圖片中的文字:

#conding=utf-8

import pytesseract
from PIL import Image

image = Image.open("./mayday.jpg")

text = pytesseract.image_to_string(image)

print(text)
asyncio & aiohttp

通過異步庫aiohttp,asyncio爬取圖片

# -*- coding:utf-8 -*-
import asyncio
import os
import time

import aiohttp
import requests


class Spider(object):
    def __init__(self):
        self.num = 1
        if "load-img" not in os.listdir("."):
            os.mkdir("load-img")
        self.path = os.path.join(os.path.abspath("."), "load-img")
        os.chdir(self.path)  # 進入文件下載路徑

    def run(self):
        start = time.time()
        for x in range(1, 101): # 爬取100張圖片,更改數(shù)值,爬取更多圖片
            links = self.__get_img_links(x)
            tasks = [asyncio.ensure_future(self.__download_img(
                (link["id"], link["links"]["download"])
            )) for link in links]
            loop = asyncio.get_event_loop()
            loop.run_until_complete(asyncio.wait(tasks))
            # if self.num >= 10:
            #     break
        end = time.time()
        print("run %s s" % (end - start))

    def __get_img_links(self, page):
        url = "https://unsplash.com/napi/photos"
        data = {
            "page": page,
            "per_page": 12,
            "order_by": "latest"
        }
        response = requests.get(url, params=data)
        if response.status_code == 200:
            return response.json()
        else:
            print("request %s" % response.status_code)

    async def __download_img(self, img):
        content = await self.__get_content(img[1])
        with open(img[0] + ".jpg", "wb") as f:
            f.write(content)
        print("load %s page success" % self.num)
        self.num += 1

    async def __get_content(self, link):
        async with aiohttp.ClientSession() as session:
            response = await session.get(link)
            content = await response.read()
            return content


def main():
    spider = Spider()
    spider.run()


if __name__ == "__main__":
    main()

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/41772.html

相關(guān)文章

  • Python爬蟲學(xué)習(xí)路線

    摘要:以下這些項目,你拿來學(xué)習(xí)學(xué)習(xí)練練手。當(dāng)你每個步驟都能做到很優(yōu)秀的時候,你應(yīng)該考慮如何組合這四個步驟,使你的爬蟲達到效率最高,也就是所謂的爬蟲策略問題,爬蟲策略學(xué)習(xí)不是一朝一夕的事情,建議多看看一些比較優(yōu)秀的爬蟲的設(shè)計方案,比如說。 (一)如何學(xué)習(xí)Python 學(xué)習(xí)Python大致可以分為以下幾個階段: 1.剛上手的時候肯定是先過一遍Python最基本的知識,比如說:變量、數(shù)據(jù)結(jié)構(gòu)、語法...

    liaoyg8023 評論0 收藏0
  • 【小白+python+selenium庫+圖片爬取+反爬+資料】超詳細新手實現(xiàn)(01)webdriv

    摘要:且本小白也親身經(jīng)歷了整個從小白到爬蟲初入門的過程,因此就斗膽在上開一個欄目,以我的圖片爬蟲全實現(xiàn)過程為例,以期用更簡單清晰詳盡的方式來幫助更多小白應(yīng)對更大多數(shù)的爬蟲實際問題。 前言: 一個月前,博主在學(xué)過python(一年前)、會一點網(wǎng)絡(luò)(能按F12)的情況下,憑著熱血和興趣,開始了pyth...

    Half 評論0 收藏0
  • 如何實現(xiàn)一個Python爬蟲框架

    摘要:這篇文章的題目有點大,但這并不是說我自覺對爬蟲這塊有多大見解,我只不過是想將自己的一些經(jīng)驗付諸于筆,對于如何寫一個爬蟲框架,我想一步一步地結(jié)合具體代碼來講述如何從零開始編寫一個自己的爬蟲框架年到如今,我花精力比較多的一個開源項目算是了,這是 showImg(https://segmentfault.com/img/remote/1460000018513379); 這篇文章的題目有點大...

    feng409 評論0 收藏0
  • 爬蟲requests模塊 入門到入獄 :基礎(chǔ)知識+實戰(zhàn)分析

    ?????? ???Hello,大家好我叫是Dream呀,一個有趣的Python博主,小白一枚,多多關(guān)照??? ???CSDN Python領(lǐng)域新星創(chuàng)作者,大二在讀,歡迎大家找我合作學(xué)習(xí) ?入門須知:這片樂園從不缺乏天才,努力才是你的最終入場券!??? ?最后,愿我們都能在看不到的地方閃閃發(fā)光,一起加油進步??? ???一萬次悲傷,依然會有Dream,我一直在最溫暖的地方等你,唱的就是我!哈哈哈~...

    yagami 評論0 收藏0
  • Python爬蟲基礎(chǔ)

    摘要:爬蟲架構(gòu)架構(gòu)組成管理器管理待爬取的集合和已爬取的集合,傳送待爬取的給網(wǎng)頁下載器。網(wǎng)頁下載器爬取對應(yīng)的網(wǎng)頁,存儲成字符串,傳送給網(wǎng)頁解析器。從文檔中獲取所有文字內(nèi)容正則匹配后記爬蟲基礎(chǔ)知識,至此足夠,接下來,在實戰(zhàn)中學(xué)習(xí)更高級的知識。 前言 Python非常適合用來開發(fā)網(wǎng)頁爬蟲,理由如下:1、抓取網(wǎng)頁本身的接口相比與其他靜態(tài)編程語言,如java,c#,c++,python抓取網(wǎng)頁文檔的接...

    bang590 評論0 收藏0
  • Python爬蟲實戰(zhàn)案例-爬取幣世界標紅快訊

    摘要:爬取幣世界標紅快訊內(nèi)容移動版引入依賴寫你自己的數(shù)據(jù)庫地址需要自己安裝客戶端數(shù)據(jù)庫表名偽造成手機寫你自己的文件地址插入了一條新數(shù)據(jù)無新數(shù)據(jù)產(chǎn)生寫你自己的文件地址時間不一致宕機使用當(dāng)前系統(tǒng)時間進行爬取時間一致正常運行主要要求掌握內(nèi)容語法 爬取幣世界標紅快訊內(nèi)容(移動版) # 引入依賴 from lxml import etree import requests import pymongo...

    red_bricks 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<