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}”后面加上?烈评,使貪婪變成非貪婪火俄。會要求正則匹配的越少越好。
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
實例:
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贴彼,所有多進程一般適用于計算密集型操作
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ū)動版本一定要支持你當前的瀏覽器版本)