URL管理器:管理待爬取的url集合和已爬取的url集合,傳送待爬取的url給網(wǎng)頁(yè)下載器。
網(wǎng)頁(yè)下載器(urllib):爬取url對(duì)應(yīng)的網(wǎng)頁(yè),存儲(chǔ)成字符串,傳送給網(wǎng)頁(yè)解析器。
網(wǎng)頁(yè)解析器(BeautifulSoup):解析出有價(jià)值的數(shù)據(jù),存儲(chǔ)下來(lái),同時(shí)補(bǔ)充url到URL管理器。
Urllib 模塊提供了讀取web頁(yè)面數(shù)據(jù)的接口,我們可以像讀取本地文件一樣讀取www和ftp上的數(shù)據(jù)。
urllib.request庫(kù)
from urllib import request
headers = { 'User-Agent': 'Mozilla/5.0 Chrome/64.0.3282.186 Safari/537.36', }
url = 'http://www.baidu.com'
req = request.Request(url, headers=headers)
response = request.urlopen(req)
data = response.read().decode('UTF-8')
print(data)
一,獲取整個(gè)頁(yè)面數(shù)據(jù)一,獲取整個(gè)頁(yè)面數(shù)據(jù)一,獲取整個(gè)頁(yè)面數(shù)據(jù)一,獲取整個(gè)頁(yè)面數(shù)據(jù)一,獲取整個(gè)頁(yè)面數(shù)據(jù)一,獲取整個(gè)頁(yè)面數(shù)據(jù)
#coding=utf-8
import urllib
def getHtml(url):
page = urllib.urlopen(url)
html = page.read()
return html
html = getHtml("http://tieba.baidu.com/p/2738151262")
print html
首先,我們定義了一個(gè)getHtml()函數(shù):
urllib.urlopen()方法用于打開一個(gè)URL地址。
read()方法用于讀取URL上的數(shù)據(jù),向getHtml()函數(shù)傳遞一個(gè)網(wǎng)址,并把整個(gè)頁(yè)面下載下來(lái)。執(zhí)行程序就會(huì)把整個(gè)網(wǎng)頁(yè)打印輸出。
二,篩選頁(yè)面中想要的數(shù)據(jù)二,篩選頁(yè)面中想要的數(shù)據(jù)二,篩選頁(yè)面中想要的數(shù)據(jù)二,篩選頁(yè)面中想要的數(shù)據(jù)二,篩選頁(yè)面中想要的數(shù)據(jù)
import re
import urllib
def getHtml(url):
page = urllib.urlopen(url)
html = page.read()
return html
def getImg(html):
reg = r'src="(.+?\.jpg)" pic_ext'
imgre = re.compile(reg)
imglist = re.findall(imgre,html)
return imglist
html = getHtml("http://tieba.baidu.com/p/2460150866")
print getImg(html)
我們又創(chuàng)建了getImg()函數(shù),用于在獲取的整個(gè)頁(yè)面中篩選需要的圖片連接。re模塊主要包含了正則表達(dá)式:
re.compile() 可以把正則表達(dá)式編譯成一個(gè)正則表達(dá)式對(duì)象.
re.findall() 方法讀取html 中包含 imgre(正則表達(dá)式)的數(shù)據(jù)。
運(yùn)行腳本將得到整個(gè)頁(yè)面中包含圖片的URL地址。
三,將頁(yè)面篩選的數(shù)據(jù)保存到本地三,將頁(yè)面篩選的數(shù)據(jù)保存到本地三,將頁(yè)面篩選的數(shù)據(jù)保存到本地三,將頁(yè)面篩選的數(shù)據(jù)保存到本地
把篩選的圖片地址通過(guò)for循環(huán)遍歷并保存到本地,代碼如下:
#coding=utf-8
import urllib
import re
def getHtml(url):
page = urllib.urlopen(url)
html = page.read()
return html
def getImg(html):
reg = r'src="(.+?\.jpg)" pic_ext'
imgre = re.compile(reg)
imglist = re.findall(imgre,html)
x = 0
for imgurl in imglist:
urllib.urlretrieve(imgurl,'%s.jpg' % x)
x+=1
return imglist
html = getHtml("http://tieba.baidu.com/p/2460150866")
print getImg(html)
************************https://www.cnblogs.com/zhaof/p/6910871.html
************************https://www.cnblogs.com/zhaof/tag/%E7%88%AC%E8%99%AB/
URL解析函數(shù)的重點(diǎn)是將URL字符串拆分為其組件,或者將URL組件組合為一個(gè)URL字符串。
urllib.parse。urlparse(allow_fragments urlstring方案=”= True)
urlunpars
其實(shí)功能和urlparse的功能相反,它是用于拼接
urljoin
這個(gè)的功能其實(shí)是做拼接的
from urllib.parse import urljoin
print(urljoin('http://www.baidu.com', 'FAQ.html'))
print(urljoin('http://www.baidu.com', 'https://pythonsite.com/FAQ.html'))
print(urljoin('http://www.baidu.com/about.html', 'https://pythonsite.com/FAQ.html'))
print(urljoin('http://www.baidu.com/about.html', 'https://pythonsite.com/FAQ.html?question=2'))
print(urljoin('http://www.baidu.com?wd=abc', 'https://pythonsite.com/index.php'))
print(urljoin('http://www.baidu.com', '?category=2#comment'))
print(urljoin('www.baidu.com', '?category=2#comment'))
print(urljoin('www.baidu.com#comment', '?category=2'))
[Requests]
**************************https://www.cnblogs.com/tangdongchu/p/4229049.html
Requests
Requests模塊安裝 pip install requests
HTTP請(qǐng)求類型
get類型
r = requests.get('https://github.com/timeline.json')
post類型
r = requests.post("http://m.ctrip.com/post")
put類型
r = requests.put("http://m.ctrip.com/put")
delete類型
r = requests.delete("http://m.ctrip.com/delete")
head類型
r = requests.head("http://m.ctrip.com/head")
options類型
r = requests.options("http://m.ctrip.com/get")
獲取響應(yīng)內(nèi)容
print r.content #以字節(jié)的方式去顯示,中文顯示為字符
print r.text #以文本的方式去顯示
URL傳遞參數(shù)
payload = {'keyword': '日本', 'salecityid': '2'}
r = requests.get("http://m.ctrip.com/webapp/tourvisa/visa_list", params=payload)
print r.url #示例為http://m.ctrip.com/webapp/tourvisa/visa_list?salecityid=2&keyword=日本
獲取/修改網(wǎng)頁(yè)編碼
r = requests.get('https://github.com/timeline.json')
print r.encoding
r.encoding = 'utf-8'
json處理
r = requests.get('https://github.com/timeline.json')
print r.json() #需要先import json
定制請(qǐng)求頭
url = 'http://m.ctrip.com'
headers = {'User-Agent' : 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19'}
r = requests.post(url, headers=headers)
print r.request.headers
復(fù)雜post請(qǐng)求
url = 'http://m.ctrip.com'
payload = {'some': 'data'}
r = requests.post(url, data=json.dumps(payload)) #如果傳遞的payload是string而不是dict,需要先調(diào)用dumps方法格式化一下
post多部分編碼文件
url = 'http://m.ctrip.com'
files = {'file': open('report.xls', 'rb')}
r = requests.post(url, files=files)
響應(yīng)狀態(tài)碼
r = requests.get('http://m.ctrip.com')
print r.status_code
響應(yīng)頭
r = requests.get('http://m.ctrip.com')
print r.headers
print r.headers['Content-Type']
print r.headers.get('content-type') #訪問響應(yīng)頭部分內(nèi)容的兩種方式
Cookies
url = 'http://example.com/some/cookie/setting/url'
r = requests.get(url)
r.cookies['example_cookie_name'] #讀取cookies
url = 'http://m.ctrip.com/cookies'
cookies = dict(cookies_are='working')
r = requests.get(url, cookies=cookies) #發(fā)送cookies
設(shè)置超時(shí)時(shí)間
r = requests.get('http://m.ctrip.com', timeout=0.001)
設(shè)置訪問代理
proxies = {
"http": "http://10.10.10.10:8888",
"https": "http://10.10.10.100:4444",
}
r = requests.get('http://m.ctrip.com', proxies=proxies)
任務(wù)隊(duì)列TaskQueue
TaskQueue的中文翻譯是“任務(wù)隊(duì)列”,顧名思義,它的作用就是把一些“任務(wù)”存儲(chǔ)在隊(duì)列中,
然后再?gòu)年?duì)列中取出任務(wù)并執(zhí)行。由于隊(duì)列是FIFO(先進(jìn)先出),所以任務(wù)隊(duì)列具有有序性。
該功能包括兩個(gè)類:Task任務(wù)類,TaskQueue任務(wù)隊(duì)列類
其中TaskQueue負(fù)責(zé):
1、開始任務(wù)
2、添加任務(wù)
3、清空任務(wù)
4、開始任務(wù)回調(diào)
5、完成隊(duì)列中所有任務(wù)回調(diào)
6、下一個(gè)任務(wù)
7、當(dāng)前任務(wù)進(jìn)度
8、隊(duì)列存儲(chǔ)所有任務(wù)
python隊(duì)列Queue
Queue
Queue是python標(biāo)準(zhǔn)庫(kù)中的線程安全的隊(duì)列(FIFO)實(shí)現(xiàn),提供了一個(gè)適用于多線程編程的先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),
即隊(duì)列,用來(lái)在生產(chǎn)者和消費(fèi)者線程之間的信息傳遞
基本FIFO隊(duì)列
class Queue.Queue(maxsize=0)
FIFO即First in First Out,先進(jìn)先出。
Queue提供了一個(gè)基本的FIFO容器,使用方法很簡(jiǎn)單,maxsize是個(gè)整數(shù),指明了隊(duì)列中能存放的數(shù)據(jù)個(gè)數(shù)的上限。
一旦達(dá)到上限,插入會(huì)導(dǎo)致阻塞,直到隊(duì)列中的數(shù)據(jù)被消費(fèi)掉。如果maxsize小于或者等于0,隊(duì)列大小沒有限制。
offer 添加一個(gè)元素并返回true 如果隊(duì)列已滿,則返回false
poll 移除并返問隊(duì)列頭部的元素 如果隊(duì)列為空,則返回null
peek 返回隊(duì)列頭部的元素 如果隊(duì)列為空,則返回null
put 添加一個(gè)元素 如果隊(duì)列滿,則阻塞
take 移除并返回隊(duì)列頭部的元素 如果隊(duì)列為空,則阻塞
element 返回隊(duì)列頭部的元素 如果隊(duì)列為空,則拋出一個(gè)NoSuchElementException異常
add 增加一個(gè)元索 如果隊(duì)列已滿,則拋出一個(gè)IIIegaISlabEepeplian異常
remove 移除并返回隊(duì)列頭部的元素 如果隊(duì)列為空,則拋出一個(gè)
NoSuchElementException異常
task_done()
意味著之前入隊(duì)的一個(gè)任務(wù)已經(jīng)完成。由隊(duì)列的消費(fèi)者線程調(diào)用。
每一個(gè)get()調(diào)用得到一個(gè)任務(wù),接下來(lái)的task_done()調(diào)用告訴隊(duì)列該任務(wù)已經(jīng)處理完畢。
如果當(dāng)前一個(gè)join()正在阻塞,它將在隊(duì)列中的所有任務(wù)都處理完時(shí)恢復(fù)執(zhí)行(即每一個(gè)由put()調(diào)用入隊(duì)的任務(wù)都有一個(gè)對(duì)應(yīng)的task_done()調(diào)用)。
join()
阻塞調(diào)用線程,直到隊(duì)列中的所有任務(wù)被處理掉。
只要有數(shù)據(jù)被加入隊(duì)列,未完成的任務(wù)數(shù)就會(huì)增加。
當(dāng)消費(fèi)者線程調(diào)用task_done()(意味著有消費(fèi)者取得任務(wù)并完成任務(wù)),未完成的任務(wù)數(shù)就會(huì)減少。
當(dāng)未完成的任務(wù)數(shù)降到0,join()解除阻塞。
put(item[, block[, timeout]])
將item放入隊(duì)列中。
1.如果可選的參數(shù)block為True且timeout為空對(duì)象(默認(rèn)的情況,阻塞調(diào)用,無(wú)超時(shí))。
2.如果timeout是個(gè)正整數(shù),阻塞調(diào)用進(jìn)程最多timeout秒,如果一直無(wú)空空間可用,拋出Full異常(帶超時(shí)的阻塞調(diào)用)。
3.如果block為False,如果有空閑空間可用將數(shù)據(jù)放入隊(duì)列,否則立即拋出Full異常
其非阻塞版本為put_nowait等同于put(item, False)
empty()
如果隊(duì)列為空,返回True,反之返回Fals
python——BeautifulSoup庫(kù)函數(shù)find_all()
find_all( name , attrs , recursive , string , **kwargs )
find_all() 方法搜索當(dāng)前tag的所有tag子節(jié)點(diǎn),并判斷是否符合過(guò)濾器的條件
Pool :
pool = pool.Pool(2)
變量 幾個(gè)進(jìn)程
功能:創(chuàng)建進(jìn)程池;
參數(shù): processes 進(jìn)程池中進(jìn)程的數(shù)量;
apply_async()
功能: 將異步的方式要執(zhí)行的事件放入進(jìn)程池;
參數(shù):
func 要執(zhí)行的函數(shù)
args 給函數(shù)按位置傳參
kwds 給函數(shù)按照鍵值傳參
返回值: 返回事件執(zhí)行后的返回值對(duì)象,可以通過(guò)調(diào)用get()函數(shù)獲取事件函數(shù)return的內(nèi)容;get() 函數(shù)獲取事件函數(shù)return內(nèi)容;
close()
功能:關(guān)閉進(jìn)程池,使其不能再加入新的事件;
#!/usr/bin/python3
import multiprocessing as mp
from time import sleep
import os
def worker(msg):
sleep(2)
print(msg)
return 'worker msg' + msg
創(chuàng)建進(jìn)程池對(duì)象,進(jìn)程池中包含4個(gè)進(jìn)程
pool = mp.Pool(processes = 4)
result = []
for i in range(10):
msg = 'hello %d'%i
#像進(jìn)程池加入要執(zhí)行的事件
r = pool.apply_async(worker,(msg,))
#pool.apply(worker,(msg,))
result.append(r)
print(result)
獲取每個(gè)事件函數(shù)的返回值
for res in result:
print(res.get())
#關(guān)閉進(jìn)程池事件加入通道,即不能再向進(jìn)程池中加入事件
pool.close()
#塞等待進(jìn)程池出來(lái)事件結(jié)束后回收進(jìn)程池
pool.join()
創(chuàng)建自己的進(jìn)程類;
1, 繼承Process類以獲取原有的屬性
2,實(shí)現(xiàn)自己需要的功能部分;
3,使用自己的類創(chuàng)建進(jìn)程即可;
from multiprocessing import Process
import time
class ClockProcess(Process):
def __init__(self, *args, **kwargs):
Process.__init__(self)
self.value = value
#在proces類中實(shí)現(xiàn),現(xiàn)在重寫這個(gè)函數(shù)
def run(self):
n = 5
while n > 0:
print('The time is {}'.\
format(time.ctime()))
time.sleep(self.value)
n -= 1
#s使用自己的進(jìn)程類創(chuàng)建進(jìn)程對(duì)象
p = ClockProcess(2)
#start后會(huì)自動(dòng)執(zhí)行run函數(shù)
p.start()
p.join()
Cookie
https://www.cnblogs.com/alamZ/p/7407007.html
https://www.cnblogs.com/adc8868/p/7256078.htmls
Cookie 是指某些網(wǎng)站服務(wù)器為了辨別用戶身份和進(jìn)行Session跟蹤,而儲(chǔ)存在用戶瀏覽器上的文本文件,Cookie可以保持登錄信息到用戶下次與服務(wù)器的會(huì)話。
Cookie原理
HTTP是無(wú)狀態(tài)的面向連接的協(xié)議, 為了保持連接狀態(tài), 引入了Cookie機(jī)制 Cookie是http消息頭中的一種屬性,包括:
Cookie名字(Name)
Cookie的值(Value)
Cookie的過(guò)期時(shí)間(Expires/Max-Age)
Cookie作用路徑(Path)
Cookie所在域名(Domain),
使用Cookie進(jìn)行安全連接(Secure)。
前兩個(gè)參數(shù)是Cookie應(yīng)用的必要條件,另外,還包括Cookie大?。⊿ize,不同瀏覽器對(duì)Cookie個(gè)數(shù)及大小限制是有差異的)。
Cookie由變量名和值組成,根據(jù) Netscape公司的規(guī)定,Cookie格式如下:
Set-Cookie: NAME=VALUE;Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE
Cookie應(yīng)用
Cookies在爬蟲方面最典型的應(yīng)用是判定注冊(cè)用戶是否已經(jīng)登錄網(wǎng)站,用戶可能會(huì)得到提示,是否在下一次進(jìn)入此網(wǎng)站時(shí)保留用戶信息以便簡(jiǎn)化登錄手續(xù)。
獲取一個(gè)有登錄信息的Cookie模擬登陸
import urllib2
# 1. 構(gòu)建一個(gè)已經(jīng)登錄過(guò)的用戶的headers信息
headers = {
"Host":"www.renren.com",
"Connection":"keep-alive",
"Upgrade-Insecure-Requests":"1",
"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",
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Language":"zh-CN,zh;q=0.8,en;q=0.6",
# 便于終端閱讀,表示不支持壓縮文件
# Accept-Encoding: gzip, deflate, sdch,
# 重點(diǎn):這個(gè)Cookie是保存了密碼無(wú)需重復(fù)登錄的用戶的Cookie,這個(gè)Cookie里記錄了用戶名,密碼(通常經(jīng)過(guò)RAS加密)
"Cookie": "anonymid=ixrna3fysufnwv; depovince=GW; _r01_=1; JSESSIONID=abcmaDhEdqIlM7riy5iMv; jebe_key=f6fb270b-d06d-42e6-8b53-e67c3156aa7e%7Cc13c37f53bca9e1e7132d4b58ce00fa3%7C1484060607478%7C1%7C1484060607173; jebecookies=26fb58d1-cbe7-4fc3-a4ad-592233d1b42e|||||; ick_login=1f2b895d-34c7-4a1d-afb7-d84666fad409; _de=BF09EE3A28DED52E6B65F6A4705D973F1383380866D39FF5; p=99e54330ba9f910b02e6b08058f780479; ap=327550029; first_login_flag=1; ln_uact=mr_mao_hacker@163.com; ln_hurl=http://hdn.xnimg.cn/photos/hdn521/20140529/1055/h_main_9A3Z_e0c300019f6a195a.jpg; t=214ca9a28f70ca6aa0801404dda4f6789; societyguester=214ca9a28f70ca6aa0801404dda4f6789; id=327550029; xnsid=745033c5; ver=7.0; loginfrom=syshome"
}
# 2. 通過(guò)headers里的報(bào)頭信息(主要是Cookie信息),構(gòu)建Request對(duì)象
urllib2.Request("http://www.renren.com/", headers = headers)
# 3. 直接訪問renren主頁(yè),服務(wù)器會(huì)根據(jù)headers報(bào)頭信息(主要是Cookie信息),判斷這是一個(gè)已經(jīng)登錄的用戶,并返回相應(yīng)的頁(yè)面
response = urllib2.urlopen(request)
# 4. 打印響應(yīng)內(nèi)容
print response.read()
通常,我們使用Request和Response對(duì)象來(lái)直接操作 Cookies:
寫入Cookies:
Response.Cookies["k1"].Value = "k1Value";
Response.Cookies["k2"]["k2-1"] = "k2-1Value";
Response.Cookies.Add(new HttpCookie("k3", "k3Value"));
讀取Cookies:
Request["k1"] ;
Request.Cookies["k1"].Value ;
Request.Cookies["k2"]["k2-1"];
Request.Cookies.Get(0).Value;
注意Request["k1"]這個(gè)大家熟悉的獲取get和post參數(shù)的方法,同時(shí)還能夠獲取Cookies的值!
另外上面語(yǔ)句中的有些是必須通過(guò)Value屬性訪問的,有些則不需要。
Cookies的Path屬性
Cookies的Path屬性表示當(dāng)前的Cookies可以作用在網(wǎng)站的那個(gè)路徑下。
python學(xué)習(xí)之——selenium元素定位
from selenium import webdriver
定位和操作節(jié)點(diǎn)
driver.find_element_by_xpath()#根據(jù)xpath路徑定位標(biāo)簽(找單個(gè))
driver.find_elements_by_xpath()#根據(jù)xpath路徑定位標(biāo)簽(找所有)
driver.find_element_by_css_selector()#根據(jù)css選擇器定位標(biāo)簽
driver.find_element_by_link_text()#根據(jù)標(biāo)簽文本內(nèi)容(完整)
driver.find_elements_by_partial_link_text()#根據(jù)標(biāo)簽文本內(nèi)容(局部)
driver.find_element_by_id()#根據(jù)id屬性尋找節(jié)點(diǎn)
driver.find_element_by_class_name()#根據(jù)class屬性尋找節(jié)點(diǎn)
Xpath
XPath (XML Path Language) 是一門在 XML 文檔中查找信息的語(yǔ)言,可用來(lái)在 XML 文檔中對(duì)元素和屬性進(jìn)行遍歷.
XPath是W3C的一個(gè)標(biāo)準(zhǔn)。它最主要的目的是為了在XML1.0或XML1.1文檔節(jié)點(diǎn)樹中定位節(jié)點(diǎn)所設(shè)計(jì).
XPath是一種表達(dá)式語(yǔ)言,它的返回值可能是節(jié)點(diǎn),節(jié)點(diǎn)集合,原子值,以及節(jié)點(diǎn)和原子值的混合等.
在學(xué)習(xí)XPath之前你應(yīng)該對(duì)XML的節(jié)點(diǎn),元素,屬性,原子值(文本),處理指令,注釋,根節(jié)點(diǎn)(文檔節(jié)點(diǎn)),命名空間以及對(duì)節(jié)點(diǎn)間的關(guān)系如:父(Parent),子(Children),兄弟(Sibling),先輩(Ancestor),后代(Descendant)等概念有所了解.
XML? from lxml import etree tag方法可以獲取標(biāo)簽名
XML 指可擴(kuò)展標(biāo)記語(yǔ)言(EXtensible Markup Language)
XML 是一種標(biāo)記語(yǔ)言,很類似 HTML
XML 的設(shè)計(jì)宗旨是傳輸數(shù)據(jù),而非顯示數(shù)據(jù)
XML 的標(biāo)簽需要我們自行定義。
XML 被設(shè)計(jì)為具有自我描述性。
XML 是 W3C 的推薦標(biāo)準(zhǔn)
路徑表達(dá)式:
表達(dá)式 描述
nodename 選取此節(jié)點(diǎn)的所有子節(jié)點(diǎn).
/ 從根節(jié)點(diǎn)選取.
// 從匹配選擇的當(dāng)前節(jié)點(diǎn)選擇文檔中的節(jié)點(diǎn),而不考慮它們的位置.
. 選取當(dāng)前節(jié)點(diǎn).
.. 選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn).
@ 選取屬性.
Selenium
Selenium是自動(dòng)化測(cè)試工具。它支持各種瀏覽器,包括 Chrome,Safari,F(xiàn)irefox 等主流界面式瀏覽器
selenium:是一個(gè)web的自動(dòng)化測(cè)試工具,可以直接運(yùn)行在瀏覽器上,但是并不自帶瀏覽器,需要有瀏覽器驅(qū)動(dòng),selenium可以根據(jù)我們的代碼指令,
讓瀏覽器自動(dòng)加載頁(yè)面,這時(shí)得到的頁(yè)面源碼是經(jīng)過(guò)瀏覽器渲染之后的,然后我們就可以在頁(yè)面源碼中尋找節(jié)點(diǎn)(動(dòng)態(tài)加載的網(wǎng)頁(yè),模擬登錄)
1.安裝 pip install selenium
- from selenium import webdriver
XXXX = webdriver.Chrome()
XXXX.get('http://www.baidu.com/')
3.定位和操作節(jié)點(diǎn)
driver.find_element_by_xpath()#根據(jù)xpath路徑定位標(biāo)簽(找單個(gè))
driver.find_elements_by_xpath()#根據(jù)xpath路徑定位標(biāo)簽(找所有)
driver.find_element_by_css_selector()#根據(jù)css選擇器定位標(biāo)簽
driver.find_element_by_link_text()#根據(jù)標(biāo)簽文本內(nèi)容(完整)
driver.find_elements_by_partial_link_text()#根據(jù)標(biāo)簽文本內(nèi)容(局部)
driver.find_element_by_id()#根據(jù)id屬性尋找節(jié)點(diǎn)
driver.find_element_by_class_name()#根據(jù)class屬性尋找節(jié)點(diǎn)
4.頁(yè)面的相關(guān)操作:
Selenium 的 WebDriver提供了各種方法來(lái)尋找元素,假設(shè)下面有一個(gè)表單輸入框如下:
<input type="text" name="user-name" id="passwd-id">
1).獲取id標(biāo)簽值
element = driver.find_element_by_id("passwd-id")
2).獲取name標(biāo)簽值
element = driver.find_element_by_name("user-name")
3).獲取標(biāo)簽名值
element = driver.find_elements_by_tag_name("input")
4).也可以通過(guò)XPath來(lái)匹配
element = driver.find_element_by_xpath("http://input[@id='passwd-id']")
Cookies操作
獲取頁(yè)面每個(gè)Cookies值,用法如下
cookies = driver.get_cookies()
cookie_dict = {i['name']:i['value'] for i in cookies}
print(cookie_dict)
添加cookies
driver.add_cookie(cookie_dict)
刪除Cookies,用法如下
刪除一個(gè)特定的cookie
driver.delete_cookie("CookieName")
刪除所有cookie
driver.delete_all_cookies()
beautifulsoup
from bs4 import BeautifulSoup
Beautiful Soup 是用Python寫的一個(gè)HTML/XML的解析器,它可以很好的處理不規(guī)范標(biāo)記并生成剖析樹(parse tree)。
它提供簡(jiǎn)單又常用的導(dǎo)航(navigating),搜索以及修改剖析樹的操作。它可以大大節(jié)省你的編程時(shí)間。
soup 就是BeautifulSoup處理格式化后的字符串,
soup.title 得到的是title標(biāo)簽,soup.p得到的是文檔中的第一個(gè)p標(biāo)簽,要想得到所有標(biāo)簽,得用find_all函數(shù)。
find_all 函數(shù)返回的是一個(gè)序列,可以對(duì)它進(jìn)行循環(huán),依次得到想到的東西.
get_text() 是返回文本,這個(gè)對(duì)每一個(gè)BeautifulSoup處理后的對(duì)象得到的標(biāo)簽都是生效的
四大對(duì)象種類
Beautiful Soup將復(fù)雜HTML文檔轉(zhuǎn)換成一個(gè)復(fù)雜的樹形結(jié)構(gòu),每個(gè)節(jié)點(diǎn)都是Python對(duì)象,所有對(duì)象可以歸納為4種:
Tag
NavigableString
BeautifulSoup
Comment
pyquery
from pyquery import PyQuery as pq
安裝 pip3 install pyquery
注意:由于 pyquery 依賴于 lxml ,要先安裝 lxml ,否則會(huì)提示失敗。
pip3 install lxml
1、.html()和.text() 獲取相應(yīng)的 HTML 塊或者文本內(nèi)容,
2、(selector):通過(guò)選擇器來(lái)獲取目標(biāo)內(nèi)容,
3、.eq(index):根據(jù)索引號(hào)獲取指定元素(index 從 0 開始)
4、.find():查找嵌套元素,
5、.filter():根據(jù) class、id 篩選指定元素,
6、.attr():獲取、修改屬性值,
7、其他操作:
#添加 class
.addClass(value):
#判斷是否包含指定的 class,返回 True 或 False
.hasClass(value):
#獲取子元素
.children():
#獲取父元素
.parents():
#獲取下一個(gè)元素
.next():
#獲取后面全部元素塊
.nextAll():
#獲取所有不匹配該選擇器的元素
.not_(selector):
re 正則表達(dá)式
爬蟲一共就四個(gè)主要步驟:
1).明確目標(biāo) (要知道你準(zhǔn)備在哪個(gè)范圍或者網(wǎng)站去搜索)
2).爬 (將所有的網(wǎng)站的內(nèi)容全部爬下來(lái))
3).取 (去掉對(duì)我們沒用處的數(shù)據(jù))
4).處理數(shù)據(jù)(按照我們想要的方式存儲(chǔ)和使用
目的 給定一個(gè)正則表達(dá)式和另一個(gè)字符串,我們可以達(dá)到如下的目的:
1.給定的字符串是否符合正則表達(dá)式的過(guò)濾邏輯(稱作“匹配”):
2.可以通過(guò)正則表達(dá)式,從字符串中獲取我們想要的特定部分。
python模塊下的正則表達(dá)式
Python 的 re 模塊
compile 函數(shù)
compile 函數(shù)用于編譯正則表達(dá)式,生成一個(gè) Pattern 對(duì)象,它的一般使用形式如下:
import re
**將正則表達(dá)式編譯成 Pattern 對(duì)象**
pattern = re.compile(r'\d+')
用pattern的方法對(duì)文本進(jìn)行匹配查找
。match 方法:從起始位置開始查找,一次匹配
。search 方法:從任何位置開始查找,一次匹配
。findall 方法:全部匹配,返回列表
。finditer 方法:全部匹配,返回迭代器
。split 方法:分割字符串,返回列表
。sub 方法:替換
amatch 只是查找字符串的頭部(也可以查找制定的位置)
。只是匹配一次,只要匹配到結(jié)果就會(huì)返回,不會(huì)查找全部結(jié)果
*******************************https://www.cnblogs.com/yeayee/p/4952022.html
多線程
python提供了兩個(gè)模塊來(lái)實(shí)現(xiàn)多線程thread 和threading
thread 有一些缺點(diǎn),在threading 得到了彌補(bǔ)學(xué)習(xí)threading
threading.Thread參數(shù)介紹
target:線程執(zhí)行的函數(shù)
name:線程名稱
args:執(zhí)行函數(shù)中需要傳遞的參數(shù),元組類型 另外:注意daemon參數(shù)
1.線程
python的thread模塊是比較底層的模塊,python的threading模塊是對(duì)thread做了一些包裝的,可以更加方便的被使用
2.多線程執(zhí)行
import threading 首先導(dǎo)入threading 模塊,這是使用多線程的前提。
split()可以將一個(gè)字符串拆分成兩部分,然后取其中的一部分。
多線程爬蟲
Queue(隊(duì)列對(duì)象) Queue是python中的標(biāo)準(zhǔn)庫(kù),可以直接import Queue引用;
隊(duì)列是線程間最常用的交換數(shù)據(jù)的形式
1.初始化: class (FIFO 先進(jìn)先出)
Queue.Queue(maxsize)
2.包中的常用方法:
Queue.qsize() 返回隊(duì)列的大小
Queue.empty() 如果隊(duì)列為空,返回True,反之False
Queue.full() 如果隊(duì)列滿了,返回True,反之False
Queue.full 與 maxsize 大小對(duì)應(yīng)
Queue.get(block,timeout)獲取隊(duì)列,timeout等待時(shí)間
創(chuàng)建一個(gè)“隊(duì)列”對(duì)象
import Queue
myqueue = Queue.Queue(maxsize = 10)
4.將一個(gè)值放入隊(duì)列中
myqueue.put(10)
將一個(gè)值從隊(duì)列中取出
myqueue.get()
多進(jìn)程
1.進(jìn)程:一個(gè)程序運(yùn)行起來(lái)后,代碼+用到的資源 稱之為進(jìn)程,它是操作系統(tǒng)分配資源的基本單元。不僅可以通過(guò)線程完成多任務(wù),進(jìn)程也是可以的
2.進(jìn)程的狀態(tài)
工作中,任務(wù)數(shù)往往大于cpu的核數(shù),即一定有一些任務(wù)正在執(zhí)行,而另外一些任務(wù)在等待cpu進(jìn)行執(zhí)行,因此導(dǎo)致了有了不同的狀態(tài)
3.進(jìn)程的創(chuàng)建-multiprocessing
multiprocessing模塊就是跨平臺(tái)版本的多進(jìn)程模塊,提供了一個(gè)Process類來(lái)代表一個(gè)進(jìn)程對(duì)象,這個(gè)對(duì)象可以理解為是一個(gè)獨(dú)立的進(jìn)程,可以執(zhí)行另外的事情
4. Process參數(shù)如下:
Process(group, target, name, args , kwargs)
target:如果傳遞了函數(shù)的引用,可以任務(wù)這個(gè)子進(jìn)程就執(zhí)行這里的代碼
args:給target指定的函數(shù)傳遞的參數(shù),以元組的方式傳遞
kwargs:給target指定的函數(shù)傳遞命名參數(shù)
name:給進(jìn)程設(shè)定一個(gè)名字,可以不設(shè)定
group:指定進(jìn)程組,大多數(shù)情況下用不到
Process創(chuàng)建的實(shí)例對(duì)象的常用方法:
start():?jiǎn)?dòng)子進(jìn)程實(shí)例(創(chuàng)建子進(jìn)程)
is_alive():判斷進(jìn)程子進(jìn)程是否還在活著
join([timeout]):是否等待子進(jìn)程執(zhí)行結(jié)束,或等待多少秒
terminate():不管任務(wù)是否完成,立即終止子進(jìn)程
Process創(chuàng)建的實(shí)例對(duì)象的常用屬性:
name:當(dāng)前進(jìn)程的別名,默認(rèn)為Process-N,N為從1開始遞增的整數(shù)
pid:當(dāng)前進(jìn)程的pid(進(jìn)程號(hào))
進(jìn)程池Pool
multiprocessing.Pool常用函數(shù)解析:
apply_async(func[, args[, kwds]]) :使用非阻塞方式調(diào)用func(并行執(zhí)行,堵塞方式必須等待上一個(gè)進(jìn)程退出才能執(zhí)行下一個(gè)進(jìn)程),args為傳遞給func的參數(shù)列表,kwds為傳遞給func的關(guān)鍵字參數(shù)列表;
close():關(guān)閉Pool,使其不再接受新的任務(wù);
terminate():不管任務(wù)是否完成,立即終止;
join():主進(jìn)程阻塞,等待子進(jìn)程的退出, 必須在close或terminate之后使用;
**********************https://www.cnblogs.com/TankMa/archive/2011/06/08/2074947.html