python爬虫笔记

爬虫

http://httpbin.org/  验证请求

1.urllib库(python3)

python内置的HTTP请求库

urllib.request  请求模块 (https://yiyibooks.cn/xx/python_352/library/urllib.request.html#module-urllib.request)

urllib.error      异常处理模块(https://yiyibooks.cn/xx/python_352/library/urllib.error.html#module-urllib.error)

urllib.parse    url解析模块(https://yiyibooks.cn/xx/python_352/library/urllib.parse.html#module-urllib.parse)

urllib.robotparser    robots.txt解析模块(https://yiyibooks.cn/xx/python_352/library/urllib.robotparser.html#module-urllib.robotparser)

 

请求:

import urllib.request

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None) 

  • url    请求的网址
  • data  加上以post请求发送,不加以get请求发送
  • [timeout, ]*     设置请求时间   超过时间报TIME OUT异常
  • cafile      
  • capath
  • cadefault
  • context

响应 

import urllib.request
response = urllib.request.urlopen('https://www.python.org')
print(type(response))#响应类型
print(response.status)#状态码
print(response.getheaders())#响应头 返回元组组成的列表
print(response.getheader('Server'))#获取特定的响应头
print(response.read().decode('utf-8'))#获得响应体

  也可以根据请求来获得响应

from urllib import request, parse
url = 'http://httpbin.org/post'
headers = {
    'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
    'Host': 'httpbin.org'
}
dict = {
    'name': 'Germey'
}
data = bytes(parse.urlencode(dict), encoding='utf8')
req = request.Request(url=url, data=data, headers=headers, method='POST')
response = request.urlopen(req)
print(response.read().decode('utf-8'))

 Handler

代理ip

proxy_handler = urllib.request.ProxyHandler({
    'http': 'http://127.0.0.1:9743',
    'https': 'https://127.0.0.1:9743'
})
opener = urllib.request.build_opener(proxy_handler)
response = opener.open('http://httpbin.org/get')
print(response.read())

cookie(保持登录会话信息

import http.cookiejar, urllib.request
cookie = http.cookiejar.CookieJar()#也可以修改CookieJar把cookie保存到本地文件(MozillaCookieJar或LWPCookieJar)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
for item in cookie:
    print(item.name+"="+item.value)

 异常

from urllib import request, error
try:
    response = request.urlopen('http://bubaidu.com/index.htm')
except error.HTTPError as e:
    print(e.reason, e.code, e.headers, sep='\n')
except error.URLError as e:
    print(e.reason)
else:
    print('Request Successfully')

url解析

 

urlparse

 

urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)#urlstring:请求地址,scheme:约束 协议,allow_fragments:将fragment拼接到前面有数据的

 

 

from urllib.parse import urlparse
result = urlparse('http://www.baidu.com/index.html;user?id=5#comment', scheme='https',allow_fragments=False)
print(type(result),result)
---------------------------------------------------------------------
<class 'urllib.parse.ParseResult'> ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=5#comment', fragment='')

 

urlunparse(将url和参数请求等进行拼接

urljoin(将两个url进行拼接,以后面的为基准)

urlencode(将字典拼接为url的请求参数

=============================================================================================

2.requests库

(request库在urllib3的基础上进行加强,推荐使用request库)

pip install requests
import requests
response = requests.get('https://www.baidu.com/')
print(type(response))
print(response.status_code)#响应状态码
print(type(response.text))
print(response.text)#响应体
print(response.cookies)#cookies

请求

  get请求

requests.get(url, params=None, **kwargs)#params以字典形式添加请求参数,也可以直接在url中写参数
#可以添加headers(有些网址不添加headers会报500的错误)

 headers = {
 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
 }
 response = requests.get("https://www.zhihu.com/explore", headers=headers)

 

    解析json

import requests
import json
response = requests.get("http://httpbin.org/get")
print(type(response.text))
print(response.json())
print(json.loads(response.text))#用json转码,结果和response.json()返回结果一样
print(type(response.json()))

    获取二进制数据(用于下载图片等)

import requests
response = requests.get("https://github.com/favicon.ico")
with open('favicon.ico', 'wb') as f:#将图片保存到本地
    f.write(response.content)#获得图片的二进制内容并写入
    f.close()

  基本post请求

import requests
data = {'name': 'germey', 'age': '22'}
headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
}
response = requests.post("http://httpbin.org/post", data=data, headers=headers)
print(response.json())

响应

 

response = requests.get('http://www.jianshu.com')
print(type(response.status_code), response.status_code)#状态码
print(type(response.headers), response.headers)#响应头(字典)
print(type(response.cookies), response.cookies)#cookies(列表)
print(type(response.url), response.url) #
print(type(response.history), response.history)#访问的历史记录

 

文件上传

files = {'file': open('favicon.ico', 'rb')}
response = requests.post("http://httpbin.org/post", files=files)
print(response.text)

会话维持(模拟登陆)

 

s = requests.Session()
s.get('http://httpbin.org/cookies/set/number/123456789')
response = s.get('http://httpbin.org/cookies')
print(response.text)

证书验证(在以https协议请求时,会先检测ssl是否是合法的)

import requests
from requests.packages import urllib3
urllib3.disable_warnings()
response = requests.get('https://www.12306.cn', verify=False)
print(response.status_code)

代理

proxies = {
  "http": "http://127.0.0.1:9743",
  "https": "https://127.0.0.1:9743",
}
response = requests.get("https://www.taobao.com", proxies=proxies)
print(response.status_code)

  也可以使用socks代理(pip3 install 'requests[socks]')

proxies = {
    'http': 'socks5://127.0.0.1:9742',
    'https': 'socks5://127.0.0.1:9742'
}

超时设置

response = requests.get("http://httpbin.org/get", timeout = 0.5)

登录验证设置

r = requests.get('http://120.27.34.24:9001', auth=('user', '123'))
print(r.status_code)

异常处理

import requests
from requests.exceptions import ReadTimeout, ConnectionError, RequestException
try:
    response = requests.get("http://httpbin.org/get", timeout = 0.5)
    print(response.status_code)
except ReadTimeout:
    print('Timeout')
except ConnectionError:
    print('Connection error')
except RequestException:
    print('Error')

===================================================================================================================

3.BeautifulSoup库

pip install BeautifulSoup4

解析库

解析器使用方法优势劣势
Python标准库BeautifulSoup(markup, "html.parser")Python的内置标准库、执行速度适中 、文档容错能力强Python 2.7.3 or 3.2.2)前的版本中文容错能力差
lxml HTML 解析器BeautifulSoup(markup, "lxml")速度快、文档容错能力强需要安装C语言库
lxml XML 解析器BeautifulSoup(markup, "xml")速度快、唯一支持XML的解析器需要安装C语言库
html5libBeautifulSoup(markup, "html5lib")最好的容错性、以浏览器的方式解析文档、生成HTML5格式的文档速度慢、不依赖外部扩展

基本使用

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.prettify())#格式化,补全代码
print(soup.title.string)#输出title标签中的内容
print(soup.title)#获取titile标签及其包裹的内容
print(soup.title.name)#获取名称  结果为title
print(soup.p.attrs['name'])#获取属性字段为的name的值
print(soup.p['name'])#获取获取属性字段为的name的值
print(soup.p.string)#获取p标签中的内容

  也可以嵌套选择

print(soup.head.title.string)

  获得子节点和子孙节点方法

#获得p标签子节点
    soup.p.contents#列表
    soup.p.children#迭代器
#获得p标签所有子孙节点
    soup.p.descendants#迭代器

  例:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.children)
for i, child in enumerate(soup.p.children):
    print(i, child)

  获得父节点和祖先节点

soup.a.parent#获取a标签的父节点
soup.a.parents#获取a标签的祖先节点(迭代器)

  获取兄弟节点

soup.a.next_siblings#获取a标签后面的兄弟节点(迭代器)
soup.a.previous_siblings#获取a标签前面的兄弟节点(迭代器)

标准选择器

find_all( name , attrs , recursive , text , **kwargs )#可根据标签名、属性、内容查找文档
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all('ul'))#获取ul标签及内容,返回结果为列表

print(soup.find_all(attrs={'id': 'list-1'}))#获取id为list-1的标签体,返回结果为列表
print(soup.find_all(id='list-1'))#特殊的字段可以用这种形式,获取id为list-1的标签体,返回结果为列表
print(soup.find_all(class_='element'))#class比较特殊

print(soup.find_all(text='Foo'))#返回的结果:内容为Foo的元组 例['Foo', 'Foo'] (多用于匹配内容)

 

find( name , attrs , recursive , text , **kwargs )#find返回单个元素,find_all返回所有元素
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选择器

 通过select()直接传入CSS选择器即可完成选择

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.select('.panel .panel-heading'))
print(soup.select('ul li'))
print(soup.select('#list-2 .element'))
print(type(soup.select('ul')[0]))
   获取属性
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for ul in soup.select('ul'):
    print(ul['id'])
    print(ul.attrs['id'])
 获取内容
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for li in soup.select('li'):
    print(li.get_text())

总结

  • 推荐使用lxml解析库,必要时使用html.parser
  • 标签选择筛选功能弱但是速度快
  • 建议使用find()、find_all() 查询匹配单个结果或者多个结果
  • 如果对CSS选择器熟悉建议使用select()
  • 记住常用的获取属性和文本值的方法

===================================================================================================================================

4.pyquery库

(pyquery比BeautifulSoup更加简易,熟悉jquery推荐使用pyquery)

from pyquery import PyQuery as pq
doc = pq(html)
print(doc('li'))#打印所有li标签及内容(css选择器)

  URL初始化

doc = pq(url='http://www.baidu.com')#将网页html代码作为参数

  文件初始化

doc = pq(filename='demo.html')#这样写文件和代码在同一路径

基本CSS选择器

from pyquery import PyQuery as pq
doc = pq(html)
print(doc('#container .list li'))
from pyquery import PyQuery as pq
doc = pq(html)
items = doc('.list')
#查找元素
lis = items.find('li')#查找子元素为li标签的
lis2 = items.children('.active')#查找所有的直接子元素class为active的

container = items.parent()#获取直接父元素
parents = items.parents()#获取父节点及所有祖先节点,也可以添加选择器

li = doc('.list .item-0.active')#.item-0.active表示一个整体 例:class="item-0 active"
print(li.siblings())#获取所有的兄弟节点

遍历

from pyquery import PyQuery as pq
doc = pq(html)#如果doc('li')获得为一个值则可以直接操作,如果多个可以进行遍历
lis = doc('li').items()#转换为generator类型
print(type(lis))
for li in lis:
    print(li)

获取信息

from pyquery import PyQuery as pq
doc = pq(html)
a = doc('.item-0.active a')

print(a.attr('href'))#获取属性为href的值
print(a.attr.href)#获取属性为href的值

print(a.text())#获取文本

print(a.html())#获取HTML

DOM操作

from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.item-0.active')

#addClass、removeClass
li.removeClass('active')#移除active属性
li.addClass('active')#添加active属性

#attr、css
li.attr('name', 'link')#修改name属性的值(没有则添加,有则修改)
li.css('font-size', '14px')#添加style属性并添加css样式

#remove
html = '''
<div class="wrap">
    Hello, World
    <p>This is a paragraph.</p>
 </div>
'''
doc = pq(html)
wrap = doc('.wrap')
print(wrap.text())#Hello, World
           This is a paragraph.
wrap.find('p').remove()#移除 print(wrap.text())#Hello, World

其他DOM方法

 

 

转载于:https://www.cnblogs.com/jokerq/p/8870158.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值