Python爬虫学习笔记

1 Python

1.1 Shebang line

IDLE下运行可以不考虑shebang line(帮助操作系统定位Python解释器),但是命令行环境下运行必需在程序首添加相应的shebang line

  • 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)

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

1.4 文本处理

  • split()语法
#  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!'
  • strip()去除首尾的字符集
'   spacious   '.strip()
#'spacious'

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

例子

去除句子中多余的空格(参考自stackoverflow)

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

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

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

1.5 剪贴板处理

使用Pyperclip可以实现复制粘贴

#! /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))

输出结果

$ ./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官方文档

Requests会根据HTTP headers对网页编码进行判别,如果判别错误,可以调用res.encoding进行修改。

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!)

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 定位

更多的内容详见官方文档

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是否书写正确,可以使用在线测试平台。

绝对路径

# 父级目录下第一个
标签 /html/body/div[1] # 通配符 *, 选择 "所有" /html/body/div[1]/* # text()选择文字 /html/body/div[1]/p[1]/text() # 选择中的指定属性值 /html/head/meta/@content

相对路径

# 下的所有text
//body//text()

# 下一层级的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')

# 获取标签内文本 hello中的'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 定位

  • 调用soup.select()方法通过CSS selectors定位
# 通过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/"]')
# [Elsie,
#  Lacie,
#  Tillie]

soup.select('a[href$="tillie"]')
# [Tillie]

soup.select('a[href*=".com/el"]')
# [Elsie]
  • find_all(),详见文档
soup.find_all("title")
# [The Dormouse's story]
soup.find_all("p", "title")
# [

The Dormouse's story

] # 通过"属性"定位 # 带有属性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']

# 获取标签内文本 hello中的'hello'
tag.text

# 获取标签名
tag.name

你可能感兴趣的:(Python爬虫学习笔记)