2

【Python】爬虫

 3 years ago
source link: https://www.guofei.site/2018/05/03/crawler.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【Python】爬虫

2018年05月03日

Author: Guofei

文章归类: Python语法 ,文章编号: 1252


版权声明:本文作者是郭飞。转载随意,但需要标明原文链接,并通知本人
原文链接:https://www.guofei.site/2018/05/03/crawler.html

Edit

基础知识

URL的一般格式为(带方括号[]的为可选项):

protocol :// hostname[:port] / path / [;parameters][?query]#fragment

URL由三部分组成:

  • protocol 是协议:http,https,ftp,file,ed2k…
  • hostname[:port]是存放资源的服务器的域名系统或IP地址(有时候要包含端口号,各种传输协议都有默认的端口号,如http的默认端口为80)。
  • 第三部分是资源的具体地址,如目录或文件名等。

爬虫步骤

  • 第一步获取网页 requests.get()
  • 第二步解析网页 BeautifulSoup
  • 第三步提取内容find_all/CSS selector
  • 第四步保存数据 txt,DB

requests

Keep-Alive & 连接池
国际化域名和 URL
带持久 Cookie 的会话
浏览器式的 SSL 认证
自动内容解码
基本/摘要式的身份认证
优雅的 key/value Cookie
自动解压
Unicode 响应体
HTTP(S) 代理支持
文件分块上传
流下载
连接超时
分块请求
支持 .netrc

快速上手

import requests

# get
r = requests.get('https://github.com/timeline.json')
# 定制url(见于下面get部分的章节)
# 定制请求头(见于下面get部分的章节)


# POST
s = requests.Session()
s.post(LOGIN_URL, data=payload, headers=dict(referer=LOGIN_URL))


# 响应内容
r.text # 文本内容,<str>
r.content # 二进制内容,<bytes>
r.json # json
r.raw # 原始内容

# 其它
r.status_code # 响应状态,200表示正常,404表示404
r.url #url
r.request # 发起请求的方式,get或其它
r.headers #头,是一个字典
r.encoding # 网页的编码方式

get

定制url

r = requests.get('http://www.guofei.site/',{'value1':'key1','value2':'key2'})
#r.url是'http://www.guofei.site/?value1=key1&value2=key2'

定制headers

# 方法1:get时定义header
headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 '
'(KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
}
r = requests.get(url, headers=headers)


# 方法2:get后定义header
r.headers.update(headers)

post

payload={'value1':'key1','value2':'key2'}
r=request.post(url,data=payload)

高级方法

伪装身份发送请求

  1. Headers
  2. Proxy代理
    requests.get(url,proxies=proxies)
    

Session和Cookie

Session对象能够跨请求保持某些参数。也会在同一个Session 实例发出的所有请求之间保持cookie。所以如果向同一主机发送多个请求,底层的TCP 连接将会被重用,从而带来显著的性能提升。

s=request.Session()
result=s.get(url)
result.cookies

身份认证

许多要求身份认证的web服务都接受HTTP Basic Auth。这是最简单的一种身份认证,并且Requests 对这种认证方式的支持是直接开箱即可用。对于更加复杂的要求身份认证的网站无效,这种需要更厉害的技术。

超时

连接超时,读取超时

# 如果你指定单一值作为timeout,这一timeout 值将会用作connect 和read 二者的timeout。如下所示:
r = requests.get('https://github.com', timeout=5)
# 如果要分别指定,就传入一个tuple:
r = requests.get('https://github.com', timeout=(3.05, 27))
# 如果远端服务器很慢,你可以让Request 永远等待,传入一个None 作为timeout 值。
r = requests.get('https://github.com', timeout=None)

错误和异常

请求和就收的过程总不是一帆风顺的,这里也有你意想不到的“惊喜”

案例

题目:写一个脚本,调用有道翻译网页版进行翻译 http://fanyi.youdao.com/

  1. 点开网页,审查元素,点击 network
  2. 刷新网页、或者重新点一次按钮、或者不操作
  3. 看每一个 Name 对应的 Preview ,找到需要的元素
  4. 找到所需元素后,点击 Preview 旁边的 Headers ,查阅关键信息
    • General
      • Request URL post实际发送到的地址
      • Status Code
    • Request Headers 很重要,里面存着网站用来反爬虫的信息。
      • User-Agent里面存着浏览器信息
    • Form Data 里面存着刚才提交的内容

BeautifulSoup

from bs4 import BeautifulSoup
import requests
r = requests.get('http://www.guofei.site/2018/04/19/statisticaltimeseries.html')
soup=BeautifulSoup(r.text,'lxml')
  • ‘html.parser’
  • ‘xml’:需要安装C语言库
  • ‘lxml’:需要安装C语言库
  • ‘html5lib’

BeautifulSoup 会把HTML文档转换成一个树形结构,每个节点都是一个Python对象 所有对象有4种

  • Tag(HTML标签)
  • NavigableString(标签的内容)
  • BeautifulSoup(文档的全部内容)
  • Comment(标签注释,特殊类型的NavigableString对象)

soup

print(soup.prettify()) # 用来看内容
soup.head # 返回Tag类型,内容是html的head
soup.p #返回Tag类型,内容是第一个 <p></p>的内容
soup.h2 #返回Tag类型
soup.span #返回Tag类型

# Tag操作
soup.p.attrs['test']='test_str'#取值或赋值
# soup.p是类似如下的形式
# <p test="test_str">Author:Guofei</p>
soup.p.string #返回bs4.element.NavigableString,内容就是对应的文本内容,如果是多节,返回空
soup.p.strings #返回 generator object 其内容是每一段的文本
soup.p.text #返回的是内部全部文本

遍历文档树

• 直接子节点-.contents  .children
soup.head.contents #是一个list
soup.head.children #是一个 list_iterator

• 所有子孙节点-.descendants
soup.head.descendants # generator object


• 节点内容-.string
• 多个内容- .strings  .stripped_strings
• 父节点-.parent
• 全部父节点-.parents
• 兄弟节点-.next_sibling .previous_sibling
• 全部兄弟节点-.next_siblings .previous_siblings
• 前后节点-.next_element .previous_element
• 所有前后节点-.next_elements .previous_elements

搜索文档树

find系列方法:

soup.find_all(name=None, attrs={'class':'content'}, recursive=True,text=None, limit=None, **kwargs) # 返回list
# <name class='content'> 对应tag.name,tag.attrs
# recursive=False 只搜索直接子节点
# text 文本内容,必须取全才能匹配到
# limit最多查找次数
# name可以接受字符串。正则表达式(re.compile("^b")。列表['p','a']。函数,函数接受tag本身,返回True/False




soup.find() #区别是只会返回第一个找到的
find_parents();find_parent()
find_next_siblings();find_next_sibling()
find_previous_siblings();find_previous_sibling()
find_all_next();find_next()
find_all_previous();find_previous()

CSS selector:

tag.select(selector, _candidate_generator=None,
limit=None)
# 通过标签名、class、id、标签和class及id的组合、属性查找
# 获取属性值、导航

您的支持将鼓励我继续创作!

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK