亲切的家政妇,桓台政务网,激光器
如果想添加 headers,可以传入headers参数来增加请求头中的headers信息。如果要将参数放在url中传递,可以利用 params 参数
import requests kw = {'wd':'长城'} headers = {"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"} # params 接收一个字典或者字符串的查询参数,字典类型自动转换为url编码,不需要urlencode() response = requests.get("http://www.baidu.com/s?", params = kw, headers = headers) # 查看响应内容,response.text 返回的是unicode格式的数据 print (response.text) # 查看响应内容,response.content返回的字节流数据 print (respones.content) # 查看完整url地址 print (response.url) # 查看响应头部字符编码 print (response.encoding) # 查看响应码 print (response.status_code)
使用response.text 时,requests 会基于 http 响应的文本编码自动解码响应内容,大多数 unicode 字符集都能被无缝地解码。 使用response.content 时,返回的是服务器响应数据的原始二进制字节流,可以用来保存图片等二进制文件。
requests默认自带的accept-encoding导致或者新浪默认发送的就是压缩之后的网页
但是为什么content.read()没有问题,因为requests,自带解压压缩网页的功能
当收到一个响应时,requests 会猜测响应的编码方式,用于在你调用response.text 方法时对响应进行解码。requests 首先在 http 头部检测是否存在指定的编码方式,如果不存在,则会使用 chardet.detect来尝试猜测编码方式(存在误差)
更推荐使用response.content.deocde()
# 如果是json文件可以直接显示 print (response.json()) # unquote将url格式的中文还原 a = requests.utils.unquote('http://www.baidu.com/f?kw=%e6%9d%e6%85%') print(a) http://www.baidu.com/f?kw=李子 通过本地环境变量 http_proxy 和 https_proxy 来配置代理: export http_proxy="http://12.34.56.79:9527" export https_proxy="https://12.34.56.79:9527"
import requests # 如果代理需要使用http basic auth,可以使用下面这种格式: proxy = { "http": "mr_mao_hacker:sffqry9r@61.158.163.130:16816" } response = requests.get("http://www.baidu.com", proxies = proxy) print (response.text)
如果是web客户端验证,需要添加 auth = (账户名, 密码)
1 import requests 2 3 auth=('test', '123456') 4 5 response = requests.get('http://192.168.199.107', auth = auth) 6 7 print (response.text)
1 import requests 2 3 response = requests.get("http://www.baidu.com/") 4 5 # 7\. 返回cookiejar对象: 6 cookiejar = response.cookies 7 8 # 8\. 将cookiejar转为字典: 9 cookiedict = requests.utils.dict_from_cookiejar(cookiejar) 10 11 print (cookiejar) 12 13 print (cookiedict)
import requests # 1\. 创建session对象,可以保存cookie值 ssion = requests.session() # 2\. 处理 headers headers = {"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"} # 3\. 需要登录的用户名和密码 data = {"email":"", "password":""} # 4\. 发送附带用户名和密码的请求,并获取登录后的cookie值,保存在ssion里 ssion.post("http://www.renren.com/plogin.do", data = data) # 5\. ssion包含用户登录后的cookie值,可以直接访问那些登录后才可以访问的页面 response = ssion.get("http://www.renren.com/410043129/profile") # 6\. 打印响应内容 print (response.text)
sslerror: ("bad handshake: error([('ssl routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",)
选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置
选取属于 bookstore 子元素的倒数第二个 book 元素
选取最前面的两个属于 bookstore 元素的子元素的 book 元素
选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00
选取 book 元素的所有 title 和 price 元素
选取文档中的所有 title 和 price 元素
选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素
获取<li> 标签下的所有 <span> 标签
获取 <li> 标签下的<a>标签里的所有 class
获取最后一个 <li> 的 <a> 的 href
从json到python的类型转化
从python原始类型向json类型的转化
chardet是一个非常优秀的编码识别模块,可通过pip安装。chardet.detect()返回字典, 其中confidence是检测精确度
将python内置类型序列化为json对象后写入文
1 import json 2 3 liststr = [{"city": "北京"}, {"name": "大刘"}] 4 json.dump(liststr, open("liststr.json","w"), ensure_ascii=false) 5 6 dictstr = {"city": "北京", "name": "大刘"} 7 json.dump(dictstr, open("dictstr.json","w"), ensure_ascii=false)
读取文件中json形式的字符串元素 转化成python类型
1 import json 2 3 strlist = json.load(open("liststr.json")) 4 print strlist 5 6 # [{u'city': u'\u5317\u4eac'}, {u'name': u'\u5927\u5218'}] 7 8 strdict = json.load(open("dictstr.json")) 9 print strdict 10 # {u'city': u'\u5317\u4eac', u'name': u'\u5927\u5218'}
import queue myqueue = queue.queue(maxsize = 10)
myqueue.put(10)
myqueue.get()
lxml 只会局部遍历,而beautiful soup 是基于html dom的,会载入整个文档,解析整个dom树,因此时间和内存开销都会大很多,所以性能要低于lxml
1 print soup.name 2 # [document] #soup 对象本身比较特殊,它的 name 即为 [document] 3 4 print soup.head.name 5 # head #对于其他内部标签,输出的值便为标签本身的名称 6 7 print soup.p.attrs 8 # {'class': ['title'], 'name': 'dromouse'} 9 # 在这里,我们把 p 标签的所有属性打印输出了出来,得到的类型是一个字典。 10 11 print soup.p['class'] # soup.p.get('class') 12 # ['title'] #还可以利用get方法,传入属性的名称,二者是等价的 13 14 soup.p['class'] = "newclass" 15 print soup.p # 可以对这些属性和内容等等进行修改 16 # <p class="newclass" name="dromouse"><b>the dormouse's story</b></p> 17 18 del soup.p['class'] # 还可以对这个属性进行删除 19 print soup.p 20 # <p name="dromouse"><b>the dormouse's story</b></p> 21 22 print soup.p.string 23 # the dormouse's story 24 25 print type(soup.p.string) 26 # in [13]: <class 'bs4.element.navigablestring'> 27 28 # comment 对象是一个特殊类型的 navigablestring 对象,其输出的内容不包括注释符号 29 print soup.a 30 # <a class="sister" href="http://example.com/elsie" id="link1"><!-- elsie --></a> 31 32 print soup.a.string 33 # elsie 34 35 print type(soup.a.string) 36 # <class 'bs4.element.comment'> 37 # tag 的 .content 属性可以将tag的子节点以列表的方式输出 38 print soup.head.contents 39 #[<title>the dormouse's story</title>] 40 print soup.head.contents[0] 41 #<title>the dormouse's story</title> 42 43 # .children 返回的是一个 list 生成器对象,通过遍历获取所有子节点 44 print soup.head.children 45 #<listiterator object at 0x7f71457f5710> 46 47 for child in soup.body.children: 48 print child 49 50 # 所有子孙节点: .descendants 属性 51 .contents 和 .children 属性仅包含tag的直接子节点,.descendants 属性可以对所有tag的子孙节点进行递归循环,和 children类似,我们也需要遍历获取其中的内容 52 for child in soup.descendants: 53 print child
1 # 调用键盘按键操作时需要引入的keys包 2 from selenium.webdriver.common.keys import keys 3 4 # 生成当前页面快照并保存 5 driver.save_screenshot("baidu.png") 6 7 # 打印网页渲染后的源代码 8 print driver.page_source 9 10 # 获取当前页面cookie 11 print driver.get_cookies() 12 13 # ctrl+a 全选输入框内容 14 driver.find_element_by_id("kw").send_keys(keys.control,'a') 15 16 # ctrl+x 剪切输入框内容 17 driver.find_element_by_id("kw").send_keys(keys.control,'x') 18 19 # 模拟enter回车键 20 driver.find_element_by_id("su").send_keys(keys.return) 21 22 # 获取当前url 23 print driver.current_url 24 25 # 关闭当前页面,如果只有一个页面,会关闭浏览器 26 # driver.close() 27 28 # 关闭浏览器 29 driver.quit()
1 # 获取id标签值 2 element = driver.find_element_by_id("passwd-id") 3 # 获取name标签值 4 element = driver.find_element_by_name("user-name") 5 # 获取标签名值 6 element = driver.find_elements_by_tag_name("input") 7 # 也可以通过xpath来匹配 8 element = driver.find_element_by_xpath("//input[@id='passwd-id']") 9 10 find_element_by_id 11 find_elements_by_name 12 find_elements_by_xpath 13 find_elements_by_link_text 14 # 上下两行区别: 15 # partial 是部分的意思,可以定位a标签文本里的部分内容 16 find_elements_by_partial_link_text 17 find_elements_by_tag_name 18 find_elements_by_class_name 19 find_elements_by_css_selector
1 #导入 actionchains 类 2 from selenium.webdriver import actionchains 3 4 # 鼠标移动到 ac 位置 5 ac = driver.find_element_by_xpath('element') 6 actionchains(driver).move_to_element(ac).perform() 7 8 9 # 在 ac 位置单击 10 ac = driver.find_element_by_xpath("elementa") 11 actionchains(driver).move_to_element(ac).click(ac).perform() 12 13 # 在 ac 位置双击 14 ac = driver.find_element_by_xpath("elementb") 15 actionchains(driver).move_to_element(ac).double_click(ac).perform() 16 17 # 在 ac 位置右击 18 ac = driver.find_element_by_xpath("elementc") 19 actionchains(driver).move_to_element(ac).context_click(ac).perform() 20 21 # 在 ac 位置左键单击hold住 22 ac = driver.find_element_by_xpath('elementf') 23 actionchains(driver).move_to_element(ac).click_and_hold(ac).perform() 24 25 # 将 ac1 拖拽到 ac2 位置 26 ac1 = driver.find_element_by_xpath('elementd') 27 ac2 = driver.find_element_by_xpath('elemente') 28 actionchains(driver).drag_and_drop(ac1, ac2).perform()
1 # 导入 select 类 2 from selenium.webdriver.support.ui import select 3 4 # 找到 name 的选项卡 5 select = select(driver.find_element_by_name('status')) 6 7 # 8 select.select_by_index(1) 9 select.select_by_value("0") 10 select.select_by_visible_text(u"未审核")
以上是三种选择下拉框的方式,它可以根据索引来选择,可以根据值来选择,可以根据文字来选择。注意:
alert = driver.switch_to_alert()
一个浏览器肯定会有很多窗口,所以我们肯定要有方法来实现窗口的切换。切换窗口的方法如下:
driver.switch_to.window("this is window name")
也可以使用 window_handles 方法来获取每个窗口的操作对象。例如:
for handle in driver.window_handles: driver.switch_to_window(handle)
driver.forward() #前进 driver.back() # 后退
1 for cookie in driver.get_cookies(): 2 print "%s -> %s" % (cookie['name'], cookie['value']) 3 4 # by name 5 driver.delete_cookie("cookiename") 6 7 # all 8 driver.delete_all_cookies()
隐式等待是等待特定的时间,显式等待是指定某一条件直到这个条件成立时继续执行。
显式等待指定某个条件,然后设置最长等待时间。如果在这个时间还没有找到元素,那么便会抛出异常了
1 from selenium import webdriver 2 from selenium.webdriver.common.by import by 3 # webdriverwait 库,负责循环等待 4 from selenium.webdriver.support.ui import webdriverwait 5 # expected_conditions 类,负责条件出发 6 from selenium.webdriver.support import expected_conditions as ec 7 8 driver = webdriver.chrome() 9 driver.get("http://www.xxxxx.com/loading") 10 try: 11 # 页面一直循环,直到 id="mydynamicelement" 出现 12 element = webdriverwait(driver, 10).until( 13 ec.presence_of_element_located((by.id, "mydynamicelement")) 14 ) 15 finally: 16 driver.quit()
如果不写参数,程序默认会 0.5s 调用一次来查看元素是否已经生成,如果本来元素就是存在的,那么会立即返回
下面是一些内置的等待条件,你可以直接调用这些条件,而不用自己写某些等待条件了
title_is
title_contains
presence_of_element_located
visibility_of_element_located
visibility_of
presence_of_all_elements_located
text_to_be_present_in_element
text_to_be_present_in_element_value
frame_to_be_available_and_switch_to_it
invisibility_of_element_located
element_to_be_clickable – it is displayed and enabled.
staleness_of
element_to_be_selected
element_located_to_be_selected
element_selection_state_to_be
element_located_selection_state_to_be
alert_is_present
不设置,默认等待时间为0,单位为秒
1 from selenium import webdriver 2 3 driver = webdriver.chrome() 4 driver.implicitly_wait(10) # seconds 5 driver.get("http://www.xxxxx.com/loading") 6 mydynamicelement = driver.find_element_by_id("mydynamicelement")
def __del__(self):
'''调用内建的稀构方法,在程序退出的时候自动调用
类似的还可以在文件打开的时候调用close,数据库链接的断开
'''
self.driver.quit()
# 默认这个方法是对象使用后自动销毁对象用的,在这里修改为对象使用后关闭浏览器
1 import pytesseract 2 from pil import image 3 4 image = image.open('test.jpg') 5 text = pytesseract.image_to_string(image) 6 print text 7 对图片进行阈值过滤和降噪处理 8 from pil import image 9 import subprocess 10 11 def cleanfile(filepath, newfilepath): 12 image = image.open(filepath) 13 14 # 对图片进行阈值过滤(低于143的置为黑色,否则为白色) 15 image = image.point(lambda x: 0 if x < 143 else 255) 16 # 重新保存图片 17 image.save(newfilepath) 18 19 # 调用系统的tesseract命令对图片进行ocr识别 20 subprocess.call(["tesseract", newfilepath, "output"]) 21 22 # 打开文件读取结果 23 with open("output.txt", 'r') as f: 24 print(f.read()) 25 26 if __name__ == "__main__": 27 cleanfile("text2.png", "text2clean.png")
scrapy保存信息的最简单的方法主要有四种,-o 输出指定格式的文件,,命令如下:
# json格式,默认为unicode编码
scrapy crawl itcast -o teachers.json
# json lines格式,默认为unicode编码
scrapy crawl itcast -o teachers.jsonl
# csv 逗号表达式,可用excel打开
scrapy crawl itcast -o teachers.csv
# xml格式
scrapy crawl itcast -o teachers.xml
response.xpath('//*[contains(@class,"odd") or contains(@class,"even")]/td[last()]/text()').extract()
0-1000随意设置,数值越低,组件的优先级越高
crawlspider使用rules来决定爬虫的爬取规则,并将匹配后的url请求提交给引擎。所以在正常情况下,crawlspider不需要单独手动返回请求了
注意:当编写爬虫规则时,避免使用parse作为回调函数。由于crawlspider使用parse方法来实现其逻辑,如果覆盖了 parse方法,crawl spider将会运行失败
1 class myspider(scrapy.spider): 2 # start_urls = ["http://www.example.com/"] 3 4 def start_requests(self): 5 url = 'http://www.renren.com/plogin.do' 6 7 # formrequest 是scrapy发送post请求的方法 8 yield scrapy.formrequest( 9 url = url, 10 formdata = {"email" : "mr_mao_hacker@163.com", "password" : "axxxxxxxe"}, 11 callback = self.parse_page 12 ) 13 def parse_page(self, response): 14 # do something
1 import scrapy 2 3 class loginspider(scrapy.spider): 4 name = 'example.com' 5 start_urls = ['http://www.example.com/users/login.php'] 6 7 def parse(self, response): 8 return scrapy.formrequest.from_response( 9 response, 10 formdata={'username': 'john', 'password': 'secret'}, 11 callback=self.after_login 12 ) 13 14 def after_login(self, response): 15 # check login succeed before going on 16 if "authentication failed" in response.body: 17 self.log("login failed", level=log.error) 18 return
downloader_middlewares = {
'scrapy_crawlera.crawleramiddleware': 600
}
crawlera_enabled = true
crawlera_user = '注册/购买的userkey'
crawlera_pass = '注册/购买的password'
1 # middlewares.py 2 3 #!/usr/bin/env python 4 # -*- coding:utf-8 -*- 5 6 import random 7 import base64 8 9 from settings import user_agents 10 from settings import proxies 11 12 # 随机的user-agent 13 class randomuseragent(object): 14 def process_request(self, request, spider): 15 useragent = random.choice(user_agents) 16 17 request.headers.setdefault("user-agent", useragent) 18 19 class randomproxy(object): 20 def process_request(self, request, spider): 21 proxy = random.choice(proxies) 22 23 if proxy['user_passwd'] is none: 24 # 没有代理账户验证的代理使用方式 25 request.meta['proxy'] = "http://" + proxy['ip_port'] 26 else: 27 # 对账户密码进行base64编码转换 28 base64_userpasswd = base64.b64encode(proxy['user_passwd']) 29 # 对应到代理服务器的信令格式里 30 request.headers['proxy-authorization'] = 'basic ' + base64_userpasswd 31 request.meta['proxy'] = "http://" + proxy['ip_port']
为什么http代理要使用base64编码: http代理的原理很简单,就是通过http协议与代理服务器建立连接,协议信令中包含要连接到的远程主机的ip和端口号,如果有需要身份验证的话还需要加上授权信息,服务器收到信令后首先进行身份验证,通过后便与远程主机建立连接,连接成功之后会返回给客户端200,表示验证通过,就这么简单,下面是具体的信令格式:
{
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'accept-language': 'en',
}
scrapy http request使用的默认header。
item_pipelines = {
'myspider.pipelines.somethingpipeline': 300,
'myspider.pipelines.itcastjsonpipeline': 800,
}
scrapy-redis提供了下面四种组件(components):(四种组件意味着这四个模块都要做相应的修改)
请使用手机"扫一扫"x
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Python 实现将numpy中的nan和inf,nan替换成对应的均值
python爬虫把url链接编码成gbk2312格式过程解析
网友评论