爬蟲基礎(chǔ)總結(jié)

requests的簡單使用:

import requests

requests是對urllib的封裝,可以實現(xiàn)urllib的所有功能

"""
:param method: 發(fā)起什么類型的請求
:param url: 請求的目標網(wǎng)址
:param params: get請求后面的參數(shù)
:param data: post的表單數(shù)據(jù)
:param json:post請求的表單數(shù)據(jù)
:param headers:字典類型 請求頭
:param cookies: 設(shè)置cookie信息教翩,模擬用戶請求
:param files: 使用它上傳文件
:param auth: 網(wǎng)站認證信息:賬號和密碼
:param timeout:設(shè)置請求超時
:type timeout:
:param allow_redirects: 是否允許重定向
:type allow_redirects:
:param proxies: 設(shè)置代理
:param verify: 忽略證書認證杆勇,默認為true,表示不忽略, Defaults to True.
"""

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

url = 'http://www.xina.com/'
req_header = {
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}

req_param = {

'wd':'小明'

}

response = requests.get(url,headers=req_header)

html = response.text

如果使用response.text出現(xiàn)亂碼饱亿,

response.content.decode('')

print(response.encoding('utf-8'))

二進制類型的數(shù)據(jù)

b_html = response.content

狀態(tài)碼

code = response.status_code

獲取響應(yīng)頭

response.headers = response.headers

獲取請求頭

r_header = response.request.headers

獲取當前請求的url的地址

current_url = response.url

response.json():可以將json字符串轉(zhuǎn)為python數(shù)據(jù)類型

print(code)

post請求

以豆瓣為例子:

import requests

form_data = {
'source': 'None',
'redir': 'https://www.douban.com',
'form_email': '18518753265',
'form_password': 'ljh12345678',
'captcha-solution': 'sneeze',
'captcha-id': 'UBvcK6xu9yysO5Ef7cYJtOaL:en',
'login': '登錄',
}

header = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
}

url = 'https://accounts.douban.com/login'

response = requests.post(url,headers=header,data=form_data)

with open('douban.html','w') as file:
file.write(response.text)

re模塊:匹配正則
re模塊的導入:import re
正則表達式:是計算機科學的一個概念蚜退。正則表達式使用單個字符串來描述、匹配一系列匹配某個句法規(guī)則的字符串彪笼。在很多文本編輯器里钻注,正則表達式通常被用來檢索、替換那些匹配某個模式的文本配猫。Regular Expression的‘Regular’一般被譯為‘正則’幅恋、‘正規(guī)’、‘常規(guī)’泵肄。此處的‘Regular’既是‘規(guī)則’捆交、‘規(guī)律’的意思淑翼,Regular Expression即‘描述某種規(guī)則的表達式’之意。簡稱:re
從左到右依次匹配零渐。

導入re模塊

import re

使用match方法進行匹配

result = re.match('正則表達式','要匹配的字符串')

如果上一步匹配到數(shù)據(jù)的話窒舟,可以使用group方法來提取數(shù)據(jù)

result.group()
re.match是用來進行正則匹配檢查的方法,若字符串匹配正則表達式诵盼,則match方法返回匹配對象(Match Object)惠豺,否則返回None(注意不是空字符串"")。匹配對象Macth Object具有g(shù)roup方法风宁,用來返回字符串的匹配部分洁墙。
re.match()能夠匹配出以“正則表達式”開頭的字符串。如果第一個字符不匹配戒财,匹配不成功热监。
re.search()在‘要匹配的字符串’中篩選匹配‘正則表達式’的字符串。只要在字符串當中有匹配的就會成功饮寞,就可以返回值孝扛。只會返回從左到右的第一個,之后的不會再返回幽崩。
re.findall()與re.search()幾乎相同苦始,唯一不同的是會返回所有匹配的值。
re.sub()將匹配到的數(shù)據(jù)進行替換
re.split()根據(jù)匹配進行切割字符串慌申,并返回一個列表
import re
ret = re.sub(r"\d+",'998',"python = 997")
print(ret)
表示字符:
單字符匹配:

     .         匹配任意一個字符(除了\n)
    [ ]        匹配中括號中列舉的字符
    \d        匹配數(shù)字陌选,即0-9
    \D        匹配非數(shù)字,既不是數(shù)字
    \s         匹配空白蹄溉,即空格咨油,tab鍵
    \S         匹配非空白
    \w        匹配單詞字符,即a-z,A-Z,0-9,_下劃線
    \W       匹配非單詞字符

例如:

import re

匹配任意一個字符

ret = re.match('.','aaksbdfii')
print(ret.group())

python中的字符串前面加上r表示原生字符串柒爵,正則表達式里使用“\”作為轉(zhuǎn)義字符役电,假如你需要匹配文本中的字符“\”,那么使用編程語言表示的正則表達式里將需要4個反斜杠棉胀,前兩個和后兩個分別用于在編程語言里轉(zhuǎn)義成反斜杠宴霸,轉(zhuǎn)換成兩個反斜杠后再在正則表達式里轉(zhuǎn)義成一個反斜杠。
import re
m = 'c:\a\b\c' # \一個只是轉(zhuǎn)義膏蚓,輸出為c:\a\b\c
print(m)
ret = re.match('c:\\',m),group() # 正則表達式將用四個反斜杠轉(zhuǎn)化成python中的兩個反斜杠瓢谢。
print(ret)

多字符匹配:

  • 匹配前一個字符出現(xiàn)0次或者無限次,即可有可無
  • 匹配前一個字符出現(xiàn)1次或者無限次驮瞧,即至少有1次
    氓扛? 匹配前一個字符出現(xiàn)1次或者0次,即要么有1次,要么沒有
    {m} 匹配前一個字符出現(xiàn)m次
    {m,} 匹配前一個字符至少出現(xiàn)m次
    {m,n}匹配騙一個字符出現(xiàn)從m到n次

表示邊界:
^ 匹配字符串開頭
$ 匹配字符串結(jié)尾
\b 匹配一個單詞邊界
\B 匹配非單詞邊界

表示匹配分組:
| 匹配左右任意一個表達式
(ab) 將括號中字符作為一個分組
\num 引用分組num匹配到的字符串
(?P<name>) 分組起別名
(?P=name) 引用別名為name分組匹配到的字符串

python正則表達式貪婪和非貪婪模式:
python里數(shù)量詞默認是貪婪的采郎,總是嘗試匹配盡可能多的字符千所;非貪婪則相反,總是嘗試匹配盡可能少的字符蒜埋。正則表達式模式中使用到通配字淫痰,那它在從左到右的順序求值時,會盡量‘抓取’滿足匹配最長字符串整份,
在“*”“待错?”“+”“{m,n}”后面加上?烈评,使貪婪變成非貪婪火俄。會要求正則匹配的越少越好。

正則.png

xpath基本語法

什么是xpath?
XPath (XML Path Language) 是一門在 XML 文檔中查找信息的語言讲冠,可用來在 XML 文檔中對元素和屬性進行遍歷瓜客。

什么是xml?
XML 指可擴展標記語言(EXtensible Markup Language)
XML 是一種標記語言,很類似 HTML
XML 的設(shè)計宗旨是傳輸數(shù)據(jù)竿开,而非顯示數(shù)據(jù)
XML 的標簽需要我們自行定義谱仪。
XML 被設(shè)計為具有自我描述性。
XML 是 W3C 的推薦標準

W3School官方文檔:http://www.w3school.com.cn/xpath/index.asp

寫一個事例:

使用 lxml 的 etree 庫

from lxml import etree
#這是一段html代碼
html = """
<div>
<ul>
<li class="item-0"><a href="link1.html">first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
"""

打印<li>標簽的元素集合

result = html.xpath('//li')

print result  # 打印<li>標簽的元素集合
print len(result)
print type(result)
print type(result[0])

輸出結(jié)果:
<type 'lxml.etree._ElementTree'>
[<Element li at 0x1014e0e18>, <Element li at 0x1014e0ef0>, <Element li at 0x1014e0f38>, <Element li at 0x1014e0f80>, <Element li at 0x1014e0fc8>]
5
<type 'list'>
<type 'lxml.etree._Element'>

獲取<li> 標簽的所有 class屬性
result = html.xpath('//li/@class')

print (result)

運行結(jié)果

['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0']

打印<li>標簽的元素集合

html = etree.parse('hello.html')
result = html.xpath('//li/a[@href="link1"]')

print(result)

運行結(jié)果:
[<Element a at 0x10ffaae18>]

. 獲取<li> 標簽下的所有 <span> 標簽
result = html.xpath('//li//span')
print(result)

運行結(jié)果:
[<Element span at 0x10d698e18>]

獲取 <li> 標簽下的<a>標簽里的所有 class

result = html.xpath('//li/a//@class')

print(result)

運行結(jié)果:
['blod']

BeautifulSoup4解析器
CSS 選擇器:BeautifulSoup4

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

CSS 選擇器:BeautifulSoup4

和 lxml 一樣胳搞,Beautiful Soup 也是一個HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 數(shù)據(jù)称杨。
導入方式:

from bs4 import BeautifulSoup

CSS選擇器

這就是另一種與 find_all 方法有異曲同工之妙的查找方法.

寫 CSS 時肌毅,標簽名不加任何修飾,類名前加.姑原,id名前加#

在這里我們也可以利用類似的方法來篩選元素悬而,用到的方法是 soup.select(),返回類型是 list

表達式 說明
* 選擇所有節(jié)點
#container 選擇id為container的節(jié)點
.container 選取所有class包含container的節(jié)點
li a 選取所有l(wèi)i下的所有a節(jié)點
div#container > ul 選取id為container的div的第一個ul子元素
a[href="http://jobbole.com"] 選取所有href屬性為jobbole.com值的a元素
a[href*=”jobole”] 選取所有href屬性包含jobbole的a元素
a[href^=“http”] 選取所有href屬性值以http開頭的a元素
a[href$=“.jpg”] 選取所有href屬性值以.jpg結(jié)尾的a元素
div:not(#container) 選取所有id非container的div屬性
li:nth-child(3) 選取第三個li元素
tr:nth-child(2n) 第偶數(shù)個tr

pyQuery解析器

安裝方法:pip3 install pyquery
由于 pyquery 依賴于 lxml 锭汛,要先安裝 lxml 笨奠,否則會提示失敗。

pip3 install lxml

bs4.png

實例:
p=pq("<head><title>Hello World!</title></head>")

獲取相應(yīng)的 HTML 塊

print (p('head').html())

獲取相應(yīng)的文本內(nèi)容

print (p('head').text())

輸出:
'''
<title>hello Word</title>
Hello World!
'''
d = pq(
"<div><p id='item-0'>test 1</p><p class='item-1'>test 2</p></div>"
)

獲取 <div> 元素內(nèi)的 HTML 塊

print (d('div').html())

獲取 id 為 item-0 的元素內(nèi)的文本內(nèi)容

print (d('#item-0').text())

獲取 class 為 item-1 的元素的文本內(nèi)容

print (d('.item-1').text())

'''輸出:
<p id="item-0">test 1</p><p class="item-1">test 2</p>
test 1
test 2
'''

d = pq(
"<div><p id='item-0'>test 1</p><p class='item-1'>test 2</p></div>"
)

獲取第二個 p 元素的文本內(nèi)容

print (d('p').eq(1).text())

'''輸出
test 2
'''

d = pq("<div><p id='item-0'>test 1</p><p class='item-1'>test 2</p></div>")

查找 <div> 內(nèi)的 p 元素

print d('div').find('p')

查找 <div> 內(nèi)的 p 元素唤殴,輸出第一個 p 元素

print d('div').find('p').eq(0)

'''輸出:
<p id="item-0">test 1</p><p class="item-1">test 2</p>
<p id="item-0">test 1</p>
'''

d = pq("<div><p id='item-0'>test 1</p><p class='item-1'>test 2</p></div>")

查找 class 為 item-1 的 p 元素

print d('p').filter('.item-1')

查找 id 為 item-0 的 p 元素

print d('p').filter('#item-0')

'''輸出:
<p class="item-1">test 2</p>
<p id="item-0">test 1</p>
'''

d = pq("<div><p id='item-0'>test 1</p><a class='item-1'>test 2</p></div>")

獲取 <p> 標簽的屬性 id

print(d('p').attr('id'))

修改 <a> 標簽的 class 屬性為 new

print(d('a').attr('class','new'))

'''輸出:
item-0
<a class="new">test 2</a>
'''

多線程多進程:

實現(xiàn)多任務(wù)的方式:多線程般婆,多進程,協(xié)程朵逝,多進程+多線程
為什么能實現(xiàn)多任務(wù)蔚袍?
并行:同時發(fā)起,同時執(zhí)行(4核,4個任務(wù))
并發(fā):同時發(fā)起啤咽,單個執(zhí)行

在python語言中晋辆,并不能夠真正意義上實現(xiàn)多線程,因為cpython解釋器
有一個全局的GIL解釋器鎖,來保證同一時刻只有一個線程在執(zhí)行

線程:是CPU執(zhí)行的基本單元宇整,占用的資源非常少瓶佳,并且線程和線程之間的資源是共享的,
線程是依賴進程存在的,多線程一般適用于IO密集/操作,線程的執(zhí)行是無序的

進程:是操作系統(tǒng)進行資源分配的節(jié)本單元鳞青,進程的執(zhí)行也是無序的霸饲,每一個進程都有自己的存儲空間,
進程之間的資源不共享盼玄,多進程能夠充分利用CPU贴彼,所有多進程一般適用于計算密集型操作

1.png

2.png

1.png

2.png

Selenium
Selenium是一個Web的自動化測試工具,最初是為網(wǎng)站自動化測試而開發(fā)的埃儿,類型像我們玩游戲用的按鍵精靈器仗,可以按指定的命令自動操作,不同是Selenium 可以直接運行在瀏覽器上童番,它支持所有主流的瀏覽器(包括PhantomJS這些無界面的瀏覽器)精钮。 Selenium 可以根據(jù)我們的指令,讓瀏覽器自動加載頁面剃斧,獲取需要的數(shù)據(jù)轨香,甚至頁面截屏,或者判斷網(wǎng)站上某些動作是否發(fā)生幼东。

Selenium 自己不帶瀏覽器臂容,不支持瀏覽器的功能,它需要與第三方瀏覽器結(jié)合在一起才能使用根蟹。但是我們有時候需要讓它內(nèi)嵌在代碼中運行脓杉,所以我們可以用一個叫 PhantomJS 的工具代替真實的瀏覽器。

可以從 PyPI 網(wǎng)站下載 Selenium庫https://pypi.python.org/simple/selenium 简逮, 也可以用第三方管理器 pip用命令安裝:

pip3 install selenium
selenium 官方參考文檔http://selenium-python.readthedocs.io/index.html

selenium中文文檔http://selenium-python-zh.readthedocs.io

Selenium也分為有界面瀏覽器和無界面瀏覽器

谷歌驅(qū)動(chromedriver)下載地址http://chromedriver.storage.googleapis.com/index.html

PhantomJS無頭瀏覽器下載地址 無界面瀏覽器引擎,無界面可腳本編程的webkit瀏覽器引擎(目前chrom也可以支持無界面請求了) 下載地址: http://phantomjs.org/download.html API使用說明: http://phantomjs.org/api/command-line.html2.1.1

火狐驅(qū)動下載路徑(GeckoDriver)https://github.com/mozilla/geckodriver/releases (2.3.8是最新的,下載的驅(qū)動版本一定要支持你當前的瀏覽器版本)

s1.png
s2.png
s3.png
s4.png
s5.png
s6.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末球散,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子散庶,更是在濱河造成了極大的恐慌蕉堰,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,331評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悲龟,死亡現(xiàn)場離奇詭異屋讶,居然都是意外死亡,警方通過查閱死者的電腦和手機须教,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評論 3 398
  • 文/潘曉璐 我一進店門丑婿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事羹奉∶胄” “怎么了?”我有些...
    開封第一講書人閱讀 167,755評論 0 360
  • 文/不壞的土叔 我叫張陵诀拭,是天一觀的道長迁筛。 經(jīng)常有香客問我,道長耕挨,這世上最難降的妖魔是什么细卧? 我笑而不...
    開封第一講書人閱讀 59,528評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮筒占,結(jié)果婚禮上贪庙,老公的妹妹穿的比我還像新娘。我一直安慰自己翰苫,他們只是感情好止邮,可當我...
    茶點故事閱讀 68,526評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著奏窑,像睡著了一般导披。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上埃唯,一...
    開封第一講書人閱讀 52,166評論 1 308
  • 那天撩匕,我揣著相機與錄音,去河邊找鬼墨叛。 笑死止毕,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的漠趁。 我是一名探鬼主播扁凛,決...
    沈念sama閱讀 40,768評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼棚潦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起膝昆,我...
    開封第一講書人閱讀 39,664評論 0 276
  • 序言:老撾萬榮一對情侶失蹤丸边,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后荚孵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妹窖,經(jīng)...
    沈念sama閱讀 46,205評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,290評論 3 340
  • 正文 我和宋清朗相戀三年收叶,在試婚紗的時候發(fā)現(xiàn)自己被綠了骄呼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,435評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蜓萄,靈堂內(nèi)的尸體忽然破棺而出隅茎,到底是詐尸還是另有隱情,我是刑警寧澤嫉沽,帶...
    沈念sama閱讀 36,126評論 5 349
  • 正文 年R本政府宣布辟犀,位于F島的核電站,受9級特大地震影響绸硕,放射性物質(zhì)發(fā)生泄漏堂竟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,804評論 3 333
  • 文/蒙蒙 一玻佩、第九天 我趴在偏房一處隱蔽的房頂上張望出嘹。 院中可真熱鬧,春花似錦咬崔、人聲如沸税稼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽娶聘。三九已至,卻和暖如春甚脉,著一層夾襖步出監(jiān)牢的瞬間丸升,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工牺氨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留狡耻,地道東北人。 一個月前我還...
    沈念sama閱讀 48,818評論 3 376
  • 正文 我出身青樓猴凹,卻偏偏與公主長得像夷狰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子郊霎,可洞房花燭夜當晚...
    茶點故事閱讀 45,442評論 2 359

推薦閱讀更多精彩內(nèi)容