Python爬蟲學習筆記

1 Python

1.1 Shebang line

IDLE下運行能夠不考慮shebang line(幫助操做系統定位Python解釋器),可是命令行環境下運行必需在程序首添加相應的shebang linecss

  • Windows
#! python3
  • OS X
#! /usr/bin/env python3
  • Linux
#! /usr/bin/python3

1.2 運行程序

# 1.修改權限
$ chmod +x pythonScript.py
# 2.執行程序
$ ./pythonScript.py

1.3 Modules安裝

開發者爲Python寫了許多優秀的第三方模塊( Modules),通常使用Pythonpip安裝。如下命令直接在命令行輸入,而不是在Python interpreter環境下輸入,不然會出現「SyntaxError: invalid syntax」的提示。(參考stackoverflow)html

# OS X/Linux
$ sudo pip3 install beautifulsoup4
# Windows
$ pip install beautifulsoup4

1.4 文本處理

#  splits s at any sequence of whitespace (blanks, newlines, tabs) and returns the remaining parts of s as a list.
s.split()
s.split(sep)

# 以regex做爲分隔符
regex = re.compile(r'##.*\uff1f')
splitContent = regex.split(content)
  • join()語法 separator.join(sequence)
'//'.join(seq)
'Go://Tear//some//strings//apart!'
'   spacious   '.strip()
#'spacious'

'www.example.com'.strip('cmowz.')
# 'example'

例子

去除句子中多餘的空格(參考自stackoverflow)python

s = ' hello world '
s.strip()
>>> 'hello world'

s = ' hello world'
s.replace(" ", "")
>>> 'helloworld'

s = ' hello   world'
' '.join(s.split())

1.5 剪貼板處理

使用Pyperclip能夠實現複製粘貼web

#! /usr/bin/env python3
import pyperclip
text = 'Hello World'
pyperclip.copy(text)
print(pyperclip.paste())

1.6 命令行參數獲取

#! /usr/bin/env python3
import sys
print('num of args: {}'.format(len(sys.argv)))
for index, elem in enumerate(sys.argv):
    print('{}: {}'.format(index, elem))

輸出結果chrome

$ ./test.py 1 2
num of args: 3
0: ./test.py
1: 1
2: 2

2 Requests

Requests will automatically decode content from the server. Most unicode charsets are seamlessly decoded. — Requests官方文檔shell

Requests會根據HTTP headers對網頁編碼進行判別,若是判別錯誤,能夠調用res.encoding進行修改。windows

import requests
res = requests.get(url)
res.raise_for_status()

# 顯示Requests自動判斷的編碼方式
print(res.encoding)
# 修改編碼方式
res.encoding='GBK'

# 以"文本"形式獲取內容
res.text
# 以"二進制"形式獲取內容
res.content

關於Unicode和字符集的基本知識能夠參考The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)api

3 Selenium

selenium安裝完成後,還須要對使用的瀏覽器進行相關配置(以Mac OS X爲例),方法以下:瀏覽器

  • Safari: OS X El Capitan及以上版本均自帶safaridriver(見/usr/bin/safaridriver),進入目錄打開safaridriver完成驗證,而後在Safari中打開Develop→Allow Remote Automation,便可正常使用。(詳見連接)
  • Chrome: 下載chromedriver,copy文件到/usr/local/bin目錄下便可正常使用。
  • Firefox:無需配置
# 測試代碼
# 若是配置成功,瀏覽器即會正常啓動; 不然報錯
from selenium import webdriver
# Safari
browser = webdriver.Safari()
# or Chrome
browser = webdriver.Chrome()
# or Firefox
browser = webdriver.Firefox()

3.1 訪問網站

from selenium import webdriver
driver = webdriver.Safari()
driver.get("http://www.python.org")

3.2 定位

更多的內容詳見官方文檔less

driver.find_element_by_class_name(name)
driver.find_elements_by_class_name(name)

driver.find_element_by_id(id)
driver.find_elements_by_id(id)

driver.find_element_by_name(name)
driver.find_elements_by_name(name)

driver.find_element_by_tag_name(name)
driver.find_elements_by_tag_name(name)

driver.find_element_by_css_selector(css)
driver.find_elements_by_css_selector(css)

driver.find_element_by_xpath(xpath)
driver.find_elements_by_xpath(xpath)
......

find_element_*返回頁面中第一個匹配的元素

find_elements_*返回頁面中全部匹配的元素,類型爲list

關於find_element_by_css_selector的使用能夠參考文章CSS selectors

3.2.1 XPath

XPath用於描述標籤的位置,與Unix系統的文件路徑的表達很是類似。瀏覽器進入開發者模式能夠直接獲取標籤對應的XPath。下面簡單列舉一下,詳細的學習能夠參考XPath Tutorial

若是須要檢查XPath是否書寫正確,可使用在線測試平臺

絕對路徑

# 父級目錄下第一個<div>標籤
/html/body/div[1]

# 通配符 *, 選擇 "全部"
/html/body/div[1]/*

# text()選擇文字
/html/body/div[1]/p[1]/text()

# 選擇<meta>中的指定屬性值
/html/head/meta/@content

相對路徑

# <body>下的全部text
//body//text()

# <a>下一層級的href屬性值
//a/@href

# 選擇帶有某一屬性的標籤
//*[@id="page"]

若是標籤訂位須要結合多屬性(參考自stackoverflow):

# 多屬性匹配
//div[@id='..' and @class='..'] 
//div[@id='..'][@class='..']
//div[@id='..' or @class='..']

3.3 獲取元素屬性

elem = driver.find_element_by_name('user')

# 獲取標籤內文本 <a>hello</a>中的'hello'
elem.text

# 獲取屬性值
elem.get_attribute('name')

# 獲取標籤名
elem.tag_name

3.4 模擬點擊/輸入

# 點擊 element
element.click()
# 有時.click()不起做用,可使用.send_keys("\n"),至關於點擊回車鍵
element.send_keys("\n")

# 輸入內容
element.send_keys("text")

# 選擇radio button
browser.find_element_by_css("input[type='radio'][value='..']").click()
# 或者 
browser.find_element_by_xpath(".//input[@type='radio' and @value='..']").click()

關於radio button的定位參考自 stackoverflow

3.5 彈框

# 得到alert對象
alert = driver.switch_to_alert()
# 選擇"確認"或者"取消"
alert.accept()
alert.dismiss()

3.6 獲取網頁源碼

html = browser.page_source

3.7 截圖

from selenium import webdriver

driver = webdriver.Safari()
driver.get('http://www.python.org/')
driver.save_screenshot('/Users/chasechoi/Documents/screenshot.png')
driver.quit()

3.8 窗口切換

當連接在新標籤中打開,driver須要使用driver.switch_to_window()切換到新標籤,不然driver會停留在原先的網頁,詳見官方手冊

# 切換窗口
driver.switch_to_window("windowName")
# 遍歷窗口
for handle in driver.window_handles:
    driver.switch_to_window(handle)
# 切換到最新窗口
driver.switch_to_window(driver.window_handles[-1])

# 切換frame 
driver.switch_to_frame("frameName")
# 返回父級frame
driver.switch_to_default_content()

3.9 關閉

詳見文檔

# 關閉tab. 只有一個tab的狀況下close()至關於quit()
driver.close()

# 關閉browser
driver.quit()

4 BeautifulSoup

詳見文檔

If you can, I recommend you install and use lxml for speed.

import bs4
soup = bs4.BeautifulSoup(markup, "lxml")

4.1 定位

# 經過id定位
soup.select("#id_value")
soup.select("a#id_value")

# 經過"屬性"定位
soup.select('a[href]')
soup.select('a[href="http://example.com/elsie"]')

soup.select('a[href^="http://example.com/"]')
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
#  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

soup.select('a[href$="tillie"]')
# [<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

soup.select('a[href*=".com/el"]')
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
soup.find_all("title")
# [<title>The Dormouse's story</title>]
soup.find_all("p", "title")
# [<p class="title"><b>The Dormouse's story</b></p>]

# 經過"屬性"定位
# 帶有屬性attrs的全部標籤
soup.find_all(attrs=True)
soup.find_all("div", attrs={"limit":True})

# 經過id定位
soup.find_all(id='id_value')

# 經過class定位
soup.find_all("a", class_="sister")

4.2 獲取元素屬性

# 獲取屬性值
tag['id']

# 獲取標籤內文本 <a>hello</a>中的'hello'
tag.text

# 獲取標籤名
tag.name