[scrapy]修改爬虫默认user agent的多种方法

python爬虫李魔佛 发表了文章 • 0 个评论 • 9969 次浏览 • 2017-12-14 16:22 • 来自相关话题

1. 创建scrapy项目:scrapy startproject headerchange2. 创建爬虫文件scrapy genspider headervalidation helloacm.com
3. 目标站点:

https://helloacm.com/api/user-agent/

这一个站点直接返回用户的User-Agent, 这样你就可以直接查看你的User-Agent是否设置成功。
尝试用浏览器打开网址 
https://helloacm.com/api/user-agent/,

网站直接返回:  
"Mozilla\/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/62.0.3202.94 Safari\/537.36"
 
3. 配置scrapy
在spider文件夹的headervalidation.py 修改为一下内容。class HeadervalidationSpider(scrapy.Spider):
name = 'headervalidation'
allowed_domains = ['helloacm.com']
start_urls = ['http://helloacm.com/api/user-agent/']

def parse(self, response):
print '*'*20
print response.body
print '*'*20
项目只是打印出response的body,也就是打印出访问的User-Agent信息。
 
运行:scrapy crawl headervalidation会发现返回的是503。 接下来,我们修改scrapy的User-Agent
 
方法1:
修改setting.py中的User-Agent# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Hello World'
然后重新运行scrapy crawl headervalidation
这个时候,能够看到正常的scrapy输出了。2017-12-14 16:17:35 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
2017-12-14 16:17:35 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (301) to <GET https://helloacm.com/api/us
er-agent/> from <GET http://helloacm.com/api/user-agent/>
2017-12-14 16:17:36 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://helloacm.com/api/user-agent/> (referer: None)

[b]********************
"Hello World"
********************
[/b]2017-12-14 16:17:37 [scrapy.core.engine] INFO: Closing spider (finished)
2017-12-14 16:17:37 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 406,
'downloader/request_count': 2,
'downloader/request_method_count/GET': 2,
'downloader/response_bytes': 796,
'downloader/response_count': 2,
'downloader/response_status_count/200': 1,
'downloader/response_status_count/301': 1,
'finish_reason': 'finished',
'finish_time': datetime.datetime(2017, 12, 14, 8, 17, 37, 29000),
'log_count/DEBUG': 3,
'log_count/INFO': 7,
'response_received_count': 1,
'scheduler/dequeued': 2,
'scheduler/dequeued/memory': 2,
'scheduler/enqueued': 2,
'scheduler/enqueued/memory': 2,
'start_time': datetime.datetime(2017, 12, 14, 8, 17, 35, 137000)}
2017-12-14 16:17:37 [scrapy.core.engine] INFO: Spider closed (finished)
 
正确设置了User-Agent
 
方法2.
修改setting中的
DEFAULT_REQUEST_HEADERS# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-Agent':'Hello World'
}
运行后也能够看到上面的输出。
 
 
方法3.
在代码中修改。class HeadervalidationSpider(scrapy.Spider):
name = 'headervalidation'
allowed_domains = ['helloacm.com']


def start_requests(self):
header={'User-Agent':'Hello World'}
yield scrapy.Request(url='http://helloacm.com/api/user-agent/',headers=header)

def parse(self, response):
print '*'*20
print response.body
print '*'*20
运行后也能够看到下面的输出。2017-12-14 16:17:35 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
2017-12-14 16:17:35 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (301) to <GET https://helloacm.com/api/us
er-agent/> from <GET http://helloacm.com/api/user-agent/>
2017-12-14 16:17:36 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://helloacm.com/api/user-agent/> (referer: None)

********************
"Hello World"
********************
2017-12-14 16:17:37 [scrapy.core.engine] INFO: Closing spider (finished)
2017-12-14 16:17:37 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
 
方法4.
在中间件中自定义Header
 
在项目目录下添加一个目录:
customerMiddleware,在目录中新建一个自定义的中间件文件:
文件名随意为 customMiddleware.py
 
文件内容为修改request User-Agent#-*-coding=utf-8-*-
from scrapy.contrib.downloadermiddleware.useragent import UserAgentMiddleware

class CustomerUserAgent(UserAgentMiddleware):
def process_request(self, request, spider):
ua='HELLO World?????????'
request.headers.setdefault('User-Agent',ua)
 
在setting中添加下面一句,以便使中间件生效。DOWNLOADER_MIDDLEWARES = {
'headerchange.customerMiddleware.customMiddleware.CustomerUserAgent':10
# 'headerchange.middlewares.MyCustomDownloaderMiddleware': 543,
}
然后重新运行,同样能够得到一样的效果。
 
原创文章,转载请注明:http://30daydo.com/article/245 

附上github的源码:https://github.com/Rockyzsu/base_function/tree/master/scrapy_demo/headerchange 
欢迎star和点赞。







如果你觉得文章对你有用,可以视乎你心情来打赏,以支持小站的服务器网络费用。
你的支持是我最大的动力!
 
PS:谢谢下面朋友的打赏
A Keung
阿贾克斯
白驹过隙
Che Long 查看全部
1. 创建scrapy项目:
scrapy startproject headerchange
2. 创建爬虫文件
scrapy genspider headervalidation helloacm.com

3. 目标站点:

https://helloacm.com/api/user-agent/

这一个站点直接返回用户的User-Agent, 这样你就可以直接查看你的User-Agent是否设置成功。
尝试用浏览器打开网址 
https://helloacm.com/api/user-agent/,

网站直接返回:  
"Mozilla\/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/62.0.3202.94 Safari\/537.36"
 
3. 配置scrapy
在spider文件夹的headervalidation.py 修改为一下内容。
class HeadervalidationSpider(scrapy.Spider):
name = 'headervalidation'
allowed_domains = ['helloacm.com']
start_urls = ['http://helloacm.com/api/user-agent/']

def parse(self, response):
print '*'*20
print response.body
print '*'*20

项目只是打印出response的body,也就是打印出访问的User-Agent信息。
 
运行:
scrapy crawl headervalidation
会发现返回的是503。 接下来,我们修改scrapy的User-Agent
 
方法1:
修改setting.py中的User-Agent
# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Hello World'

然后重新运行
scrapy crawl headervalidation

这个时候,能够看到正常的scrapy输出了。
2017-12-14 16:17:35 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
2017-12-14 16:17:35 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (301) to <GET https://helloacm.com/api/us
er-agent/> from <GET http://helloacm.com/api/user-agent/>
2017-12-14 16:17:36 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://helloacm.com/api/user-agent/> (referer: None)

[b]********************
"Hello World"
********************
[/b]2017-12-14 16:17:37 [scrapy.core.engine] INFO: Closing spider (finished)
2017-12-14 16:17:37 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 406,
'downloader/request_count': 2,
'downloader/request_method_count/GET': 2,
'downloader/response_bytes': 796,
'downloader/response_count': 2,
'downloader/response_status_count/200': 1,
'downloader/response_status_count/301': 1,
'finish_reason': 'finished',
'finish_time': datetime.datetime(2017, 12, 14, 8, 17, 37, 29000),
'log_count/DEBUG': 3,
'log_count/INFO': 7,
'response_received_count': 1,
'scheduler/dequeued': 2,
'scheduler/dequeued/memory': 2,
'scheduler/enqueued': 2,
'scheduler/enqueued/memory': 2,
'start_time': datetime.datetime(2017, 12, 14, 8, 17, 35, 137000)}
2017-12-14 16:17:37 [scrapy.core.engine] INFO: Spider closed (finished)

 
正确设置了User-Agent
 
方法2.
修改setting中的
DEFAULT_REQUEST_HEADERS
# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-Agent':'Hello World'
}

运行后也能够看到上面的输出。
 
 
方法3.
在代码中修改。
class HeadervalidationSpider(scrapy.Spider):
name = 'headervalidation'
allowed_domains = ['helloacm.com']


def start_requests(self):
header={'User-Agent':'Hello World'}
yield scrapy.Request(url='http://helloacm.com/api/user-agent/',headers=header)

def parse(self, response):
print '*'*20
print response.body
print '*'*20

运行后也能够看到下面的输出。
2017-12-14 16:17:35 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
2017-12-14 16:17:35 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (301) to <GET https://helloacm.com/api/us
er-agent/> from <GET http://helloacm.com/api/user-agent/>
2017-12-14 16:17:36 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://helloacm.com/api/user-agent/> (referer: None)

********************
"Hello World"
********************
2017-12-14 16:17:37 [scrapy.core.engine] INFO: Closing spider (finished)
2017-12-14 16:17:37 [scrapy.statscollectors] INFO: Dumping Scrapy stats:

 
方法4.
在中间件中自定义Header
 
在项目目录下添加一个目录:
customerMiddleware,在目录中新建一个自定义的中间件文件:
文件名随意为 customMiddleware.py
 
文件内容为修改request User-Agent
#-*-coding=utf-8-*-
from scrapy.contrib.downloadermiddleware.useragent import UserAgentMiddleware

class CustomerUserAgent(UserAgentMiddleware):
def process_request(self, request, spider):
ua='HELLO World?????????'
request.headers.setdefault('User-Agent',ua)

 
在setting中添加下面一句,以便使中间件生效。
DOWNLOADER_MIDDLEWARES = {
'headerchange.customerMiddleware.customMiddleware.CustomerUserAgent':10
# 'headerchange.middlewares.MyCustomDownloaderMiddleware': 543,
}

然后重新运行,同样能够得到一样的效果。
 
原创文章,转载请注明:http://30daydo.com/article/245 

附上github的源码:https://github.com/Rockyzsu/base_function/tree/master/scrapy_demo/headerchange 
欢迎star和点赞。


mm_facetoface_collect_qrcode_1513241363991_副本1_副本_副本.png


如果你觉得文章对你有用,可以视乎你心情来打赏,以支持小站的服务器网络费用。
你的支持是我最大的动力!
 
PS:谢谢下面朋友的打赏
A Keung
阿贾克斯
白驹过隙
Che Long

matplotlib pie饼图 lable设置中文乱码 解决办法

李魔佛 发表了文章 • 0 个评论 • 13161 次浏览 • 2017-11-03 17:10 • 来自相关话题

X=[1,1,1,1,1,1,1]
labels = [u'百度',u'京东',u'陆金所',u'工行',u'招行',u'华泰',u'国金',u'广发',u'QQ']
plt.figure()
p = plt.pie(X,labels=labels) 





(实际X的数据为其他数据,这里只是简单的设为1的列表)
 
google了些资料,找到以下可行的解决办法:
 
找一个系统自带的中文字体文件的路径
比如这一个:C:\Windows\winsxs\amd64_microsoft-windows-font-truetype-simfang_31bf3856ad364e35_6.1.7600.16385_none_e417159f3b4eb1b7\simfang.ttf
 
把路径拷贝下来。
 
然后在代码中设置: for front in p[1]:
front.set_fontproperties(mpl.font_manager.FontProperties(
fname='C:\Windows\winsxs\amd64_microsoft-windows-font-truetype-simfang_31bf3856ad364e35_6.1.7600.16385_none_e417159f3b4eb1b7\simfang.ttf'))
 
把 p中的font属性强制改为指向我们想要的字体路径,这样就可以达到修改饼图上的中文乱码问题了。
 





 
正常显示中文了。
 
在linux下同理,只需要下载一个字体文件,放在某个目录,然后在代码中指定字体的位置。
字体文件下载: https://fontzone.net/download/simhei
然后运行: $locate -b '\mpl-data'
看看mpl目录的位置,把字体文件放到fonts/ttf这个目录下面,
如果使用代码设定,如下:#!/usr/bin/env python
#coding:utf-8
"""a demo of matplotlib"""
import matplotlib as mpl
from matplotlib import pyplot as plt
mpl.rcParams[u'font.sans-serif'] = ['simhei']
mpl.rcParams['axes.unicode_minus'] = False
years = [1950, 1960, 1970, 1980, 1990, 2000, 2010]
gdp = [300.2, 543.3, 1075.9, 2862.5, 5979.6, 10289.7, 14958.3]
#创建一副线图,x轴是年份,y轴是gdp
plt.plot(years, gdp, color='green', marker='o', linestyle='solid')
#添加一个标题
plt.title(u'名义GDP')
#给y轴加标记
plt.ylabel(u'十亿美元')
plt.show()
 
PS:
在树莓派上回出现的问题:
UserWarning: findfont: Font family [u'sans-serif'] not found. Falling back to DejaVu Sanspi@raspb DejaVu Sans^CserWarning: findfont: Font family [u'sans-serif'] not found. Falling back to
 
这个时候只要安装一个font-manager就可以了:
sudo apt install font-manager
 
OK ! 查看全部
    X=[1,1,1,1,1,1,1]
labels = [u'百度',u'京东',u'陆金所',u'工行',u'招行',u'华泰',u'国金',u'广发',u'QQ']
plt.figure()
p = plt.pie(X,labels=labels)
 

matplot_乱码.png

(实际X的数据为其他数据,这里只是简单的设为1的列表)
 
google了些资料,找到以下可行的解决办法:
 
找一个系统自带的中文字体文件的路径
比如这一个:C:\Windows\winsxs\amd64_microsoft-windows-font-truetype-simfang_31bf3856ad364e35_6.1.7600.16385_none_e417159f3b4eb1b7\simfang.ttf
 
把路径拷贝下来。
 
然后在代码中设置:
    for front in p[1]:
front.set_fontproperties(mpl.font_manager.FontProperties(
fname='C:\Windows\winsxs\amd64_microsoft-windows-font-truetype-simfang_31bf3856ad364e35_6.1.7600.16385_none_e417159f3b4eb1b7\simfang.ttf'))

 
把 p中的font属性强制改为指向我们想要的字体路径,这样就可以达到修改饼图上的中文乱码问题了。
 

matplot_乱码2.png

 
正常显示中文了。
 
在linux下同理,只需要下载一个字体文件,放在某个目录,然后在代码中指定字体的位置。
字体文件下载: https://fontzone.net/download/simhei
然后运行: $locate -b '\mpl-data'
看看mpl目录的位置,把字体文件放到fonts/ttf这个目录下面,
如果使用代码设定,如下:
#!/usr/bin/env python
#coding:utf-8
"""a demo of matplotlib"""
import matplotlib as mpl
from matplotlib import pyplot as plt
mpl.rcParams[u'font.sans-serif'] = ['simhei']
mpl.rcParams['axes.unicode_minus'] = False
years = [1950, 1960, 1970, 1980, 1990, 2000, 2010]
gdp = [300.2, 543.3, 1075.9, 2862.5, 5979.6, 10289.7, 14958.3]
#创建一副线图,x轴是年份,y轴是gdp
plt.plot(years, gdp, color='green', marker='o', linestyle='solid')
#添加一个标题
plt.title(u'名义GDP')
#给y轴加标记
plt.ylabel(u'十亿美元')
plt.show()

 
PS:
在树莓派上回出现的问题:
UserWarning: findfont: Font family [u'sans-serif'] not found. Falling back to DejaVu Sanspi@raspb DejaVu Sans^CserWarning: findfont: Font family [u'sans-serif'] not found. Falling back to
 
这个时候只要安装一个font-manager就可以了:
sudo apt install font-manager
 
OK !

You must either define the environment variable DJANGO_SETTINGS_MODULE

李魔佛 发表了文章 • 0 个评论 • 5197 次浏览 • 2017-10-08 12:41 • 来自相关话题

代码如下:
from django import template
def template_usage():
t = template.Template('My name is {{ name }}')
c = template.Context({'name':'Rocky'})
print t.render(c)

template_usage()
就出错了。
 
这个原因一般就是直接使用python或者ipython交互解析器造成的。
 
你需要切换到你的django目录,然后使用python manager.py shell 运行, 然后执行上面的函数或者代码, 就不会再出现这个错误了
 
django.core.exceptions.ImproperlyConfigured: Requested setting TEMPLATES, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
 
  查看全部
代码如下:
from django import template
def template_usage():
t = template.Template('My name is {{ name }}')
c = template.Context({'name':'Rocky'})
print t.render(c)

template_usage()

就出错了。
 
这个原因一般就是直接使用python或者ipython交互解析器造成的。
 
你需要切换到你的django目录,然后使用python manager.py shell 运行, 然后执行上面的函数或者代码, 就不会再出现这个错误了
 
django.core.exceptions.ImproperlyConfigured: Requested setting TEMPLATES, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
 
 

儿歌多多 下载全部儿歌视频文件

python爬虫李魔佛 发表了文章 • 0 个评论 • 15789 次浏览 • 2017-09-28 23:44 • 来自相关话题

嗅探app的下载路径,然后抓取数据
 
http://30daydo.com/article/236 

更新 ******** 2018-01-09*************
最近才发现以前曾经挖了这个坑,现在来完成它吧。
 
儿歌多多在爱奇艺的视频网站上也有全集,所以目标转为抓取iqiyi的儿歌多多视频列表。 
github上有一个现成的下载iqiyi的第三方库,可以通过python调用这个库来实现下载功能。
 
代码使用python3来实现。
 
1. 打开网页 http://www.iqiyi.com/v_19rrkwcx6w.html#curid=455603300_26b870cbb10342a6b8a90f7f0b225685
 
这个是第一集的儿歌多多,url后面的curid只是一个随机的字符串,可以直接去掉。
 
url=“http://www.iqiyi.com/v_19rrkwcx6w.htm”
浏览器直接查看源码,里面直接包含了1-30集的视频url,那么要做的就是提取这30个url
 
先抓取网页内容:session = requests.Session()
def getContent(url):
try:
ret = session.get(url)
except:
return None
if ret.status_code==200:
return ret.text
else:
return None
然后提取内容中的url





点击查看大图

提取div标签中的属性 data-current-count=1的。然后选择子节点中的li标签,提取li中的a中的href链接即可。 content = getContent(url)
root = etree.HTML(content)
elements=root.xpath('//div[@data-current-count="1"]//li/a/@href')
for items in elements:
song_url = items.replace('//','')
song_url=song_url.strip()
print(song_url)







2. 有了url,就可以下载这个页面的中的内容了。
这里我使用的是一个第三方的视频下载库,you-get。(非常好用,fork到自己仓库研究 https://github.com/Rockyzsu/you-get)
 
使用方法:

python you-get -d --format=HD url
 
you-get 需要下载一个ffmpeg.exe的文件来解码视频流的,去官网就可以免费下载。
 
url就是你要下载的url地址,format可以选择高清还是其他格式的,我这里选择的是HD。
 
在python脚本里面调用另外一个python脚本,可以使用subprocess来调用。 p=subprocess.Popen('python you-get -d --format=HD {}'.format(song_url),stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
output,error = p.communicate()
print(output)
print(error)
p.wait()
上面的song_url 就是接着最上面那个代码的。
 
 
完整代码如下:#-*-coding=utf-8-*-
import requests
from lxml import etree
import subprocess
session = requests.Session()
def getContent(url):
# url='http://www.iqiyi.com/v_19rrkwcx6w.html'
try:
ret = session.get(url)
# except Exception,e:
except:
# print e
return None
if ret.status_code==200:
return ret.text
else:
return None

def getUrl():
url='http://www.iqiyi.com/v_19rrkwcx6w.html'
url2='http://www.iqiyi.com/v_19rrl2td7g.html' # 31-61
content = getContent(url)
root = etree.HTML(content)
elements=root.xpath('//div[@data-current-count="1"]//li/a/@href')
for items in elements:
song_url = items.replace('//','')
song_url=song_url.strip()
print(song_url)
p=subprocess.Popen('python you-get -d --format=HD {}'.format(song_url),stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
output,error = p.communicate()
print(output)
print(error)
p.wait()

def main():
getUrl()

if __name__ == '__main__':
main()
上面的是1-30集的,全部集数现在是120集,31-60的在url 
http://www.iqiyi.com/v_19rrl2td7g.html
 
这个url只要你选择iqiyi视频的右边栏,就会自动变化。 同理也可以找到61-120的url,然后替换到上面代码中最开始的url就可以了。(这里因为页码少,所以就没有用循环去做)
 
最终的下载结果:





 
 
后面修改了下代码,判断文件是不是已经存在,存在的会就不下载,对于长时间下载100多个文件很有用,如果掉线了,重新下载就不会去下载那些已经下好的。#-*-coding=utf-8-*-
import sys,os
import requests
from lxml import etree
import subprocess
session = requests.Session()
def getContent(url):
# url='http://www.iqiyi.com/v_19rrkwcx6w.html'
try:
ret = requests.get(url)
ret.encoding='utf-8'
# except Exception,e:
except:
# print e
return None
if ret.status_code==200:
return ret.text
else:
return None

def getUrl():
url='http://www.iqiyi.com/v_19rrkwcx6w.html'
url2='http://www.iqiyi.com/v_19rrl2td7g.html' # 31-61
content = getContent(url)
if not content:
print "network issue, retry"
exit(0)
root = etree.HTML(content,parser=etree.HTMLParser(encoding='utf-8'))
elements=root.xpath('//div[@data-current-count="1"]//li')
for items in elements:
url_item=items.xpath('.//a/@href')[0]
song_url = url_item.replace('//','')
song_url=song_url.strip()
print(song_url)
# name=items.xpath('.//span[@class="item-num"]/text()')[0]
name=items.xpath('.//span[@class="item-num"]/text()')[0].encode('utf-8').strip()+\
' '+items.xpath('.//span[@class="item-txt"]/text()')[0].encode('utf-8').strip()+'.mp4'
name= '儿歌多多 '+name
name=name.decode('utf-8')
filename=os.path.join(os.getcwd(),name)
print filename
if os.path.exists(filename):
continue
p=subprocess.Popen('python you-get -d --format=HD {}'.format(song_url),stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
output,error = p.communicate()
print(output)
print(error)
p.wait()


def main():
getUrl()

if __name__ == '__main__':
main()

下载下来大概300多集,直接拷贝到平板上离线播放,再也不卡了。
 
原创地址:http://30daydo.com/article/236 
转载请注明出处
 
  查看全部
嗅探app的下载路径,然后抓取数据
 
http://30daydo.com/article/236 

更新 ******** 2018-01-09*************
最近才发现以前曾经挖了这个坑,现在来完成它吧。
 
儿歌多多在爱奇艺的视频网站上也有全集,所以目标转为抓取iqiyi的儿歌多多视频列表。 
github上有一个现成的下载iqiyi的第三方库,可以通过python调用这个库来实现下载功能。
 
代码使用python3来实现。
 
1. 打开网页 http://www.iqiyi.com/v_19rrkwcx6w.html#curid=455603300_26b870cbb10342a6b8a90f7f0b225685
 
这个是第一集的儿歌多多,url后面的curid只是一个随机的字符串,可以直接去掉。
 
url=“http://www.iqiyi.com/v_19rrkwcx6w.htm”
浏览器直接查看源码,里面直接包含了1-30集的视频url,那么要做的就是提取这30个url
 
先抓取网页内容:
session = requests.Session()
def getContent(url):
try:
ret = session.get(url)
except:
return None
if ret.status_code==200:
return ret.text
else:
return None

然后提取内容中的url

url.GIF

点击查看大图

提取div标签中的属性 data-current-count=1的。然后选择子节点中的li标签,提取li中的a中的href链接即可。
    content = getContent(url)
root = etree.HTML(content)
elements=root.xpath('//div[@data-current-count="1"]//li/a/@href')
for items in elements:
song_url = items.replace('//','')
song_url=song_url.strip()
print(song_url)







2. 有了url,就可以下载这个页面的中的内容了。
这里我使用的是一个第三方的视频下载库,you-get。(非常好用,fork到自己仓库研究 https://github.com/Rockyzsu/you-get)
 
使用方法:

python you-get -d --format=HD url
 
you-get 需要下载一个ffmpeg.exe的文件来解码视频流的,去官网就可以免费下载。
 
url就是你要下载的url地址,format可以选择高清还是其他格式的,我这里选择的是HD。
 
在python脚本里面调用另外一个python脚本,可以使用subprocess来调用。
        p=subprocess.Popen('python you-get -d --format=HD {}'.format(song_url),stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
output,error = p.communicate()
print(output)
print(error)
p.wait()

上面的song_url 就是接着最上面那个代码的。
 
 
完整代码如下:
#-*-coding=utf-8-*-
import requests
from lxml import etree
import subprocess
session = requests.Session()
def getContent(url):
# url='http://www.iqiyi.com/v_19rrkwcx6w.html'
try:
ret = session.get(url)
# except Exception,e:
except:
# print e
return None
if ret.status_code==200:
return ret.text
else:
return None

def getUrl():
url='http://www.iqiyi.com/v_19rrkwcx6w.html'
url2='http://www.iqiyi.com/v_19rrl2td7g.html' # 31-61
content = getContent(url)
root = etree.HTML(content)
elements=root.xpath('//div[@data-current-count="1"]//li/a/@href')
for items in elements:
song_url = items.replace('//','')
song_url=song_url.strip()
print(song_url)
p=subprocess.Popen('python you-get -d --format=HD {}'.format(song_url),stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
output,error = p.communicate()
print(output)
print(error)
p.wait()

def main():
getUrl()

if __name__ == '__main__':
main()

上面的是1-30集的,全部集数现在是120集,31-60的在url 
http://www.iqiyi.com/v_19rrl2td7g.html
 
这个url只要你选择iqiyi视频的右边栏,就会自动变化。 同理也可以找到61-120的url,然后替换到上面代码中最开始的url就可以了。(这里因为页码少,所以就没有用循环去做)
 
最终的下载结果:

ergeduoduo.GIF

 
 
后面修改了下代码,判断文件是不是已经存在,存在的会就不下载,对于长时间下载100多个文件很有用,如果掉线了,重新下载就不会去下载那些已经下好的。
#-*-coding=utf-8-*-
import sys,os
import requests
from lxml import etree
import subprocess
session = requests.Session()
def getContent(url):
# url='http://www.iqiyi.com/v_19rrkwcx6w.html'
try:
ret = requests.get(url)
ret.encoding='utf-8'
# except Exception,e:
except:
# print e
return None
if ret.status_code==200:
return ret.text
else:
return None

def getUrl():
url='http://www.iqiyi.com/v_19rrkwcx6w.html'
url2='http://www.iqiyi.com/v_19rrl2td7g.html' # 31-61
content = getContent(url)
if not content:
print "network issue, retry"
exit(0)
root = etree.HTML(content,parser=etree.HTMLParser(encoding='utf-8'))
elements=root.xpath('//div[@data-current-count="1"]//li')
for items in elements:
url_item=items.xpath('.//a/@href')[0]
song_url = url_item.replace('//','')
song_url=song_url.strip()
print(song_url)
# name=items.xpath('.//span[@class="item-num"]/text()')[0]
name=items.xpath('.//span[@class="item-num"]/text()')[0].encode('utf-8').strip()+\
' '+items.xpath('.//span[@class="item-txt"]/text()')[0].encode('utf-8').strip()+'.mp4'
name= '儿歌多多 '+name
name=name.decode('utf-8')
filename=os.path.join(os.getcwd(),name)
print filename
if os.path.exists(filename):
continue
p=subprocess.Popen('python you-get -d --format=HD {}'.format(song_url),stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
output,error = p.communicate()
print(output)
print(error)
p.wait()


def main():
getUrl()

if __name__ == '__main__':
main()


下载下来大概300多集,直接拷贝到平板上离线播放,再也不卡了。
 
原创地址:http://30daydo.com/article/236 
转载请注明出处
 
 

30天学会django

李魔佛 发表了文章 • 0 个评论 • 3414 次浏览 • 2017-09-17 23:40 • 来自相关话题

没错,最近30天开始要折腾这玩意。
 
先放个标题出来。 每天不定时更新。
 
 
我用的视频教程是cstv的那一个系列教程。
 
不推荐那个django中文手册的,因为文档比较旧,很多命令或者代码是无法再新版的django上运行通过的。 这个会比较打击人。
 

  查看全部
没错,最近30天开始要折腾这玩意。
 
先放个标题出来。 每天不定时更新。
 
 
我用的视频教程是cstv的那一个系列教程。
 
不推荐那个django中文手册的,因为文档比较旧,很多命令或者代码是无法再新版的django上运行通过的。 这个会比较打击人。
 

 

怎么判断你用的代理是高度匿名还是透明的

python爬虫李魔佛 发表了文章 • 0 个评论 • 9039 次浏览 • 2017-09-06 20:42 • 来自相关话题

先介绍下什么事高度匿名代理和透明代理.
 

你用透明代理上QQ,对方还是能看到你的本来的IP
只有用匿名和高匿名才不会被对方看到IP.

详细的说:
匿名代理:
如果从隐藏使用代理用户的级别上划分,代理可以分为三种,即高度匿名代理、普通匿名代理和透明代理。

(1)高度匿名代理不改变客户机的请求,这样在服务器看来就像有个真正的客户浏览器在访问它,这时客户的真实IP是隐藏的,服务器端不会认为我们使用了代理。

(2)普通匿名代理能隐藏客户机的真实IP,但会改变我们的请求信息,服务器端有可能会认为我们使用了代理。不过使用此种代理时,虽然被访问的网站不能知道你的ip地址,但仍然可以知道你在使用代理,当然某些能够侦测ip的网页仍然可以查到你的ip。

(3)透明代理,它不但改变了我们的请求信息,还会传送真实的IP地址。
三者隐藏使用代理者身份的级别依次为高度匿名代理最隐蔽,其次是普通匿名代理,最差的是透明代理。
 
 
把你找到的代理iP,在你的浏览器里设置一下, 具体可以百度谷歌, 不难.
 
然后用浏览器打开这个网站:
 
http://members.3322.org/dyndns/getip
 
网站返回很简单, 就是你当前的iP地址. 据目前使用那么多的检测iP地址的网站来看,这个网站最准.
 
用代理打开这个网站,如果网站显示的是你代理IP,那么说明你的ip是高度匿名的.
如果网站显示的是有2个ip,那么你的代理是透明的, 第一个ip是你的原始ip,而第二个ip是你用的代理ip.
 





 
  查看全部
先介绍下什么事高度匿名代理和透明代理.
 

你用透明代理上QQ,对方还是能看到你的本来的IP
只有用匿名和高匿名才不会被对方看到IP.

详细的说:
匿名代理:
如果从隐藏使用代理用户的级别上划分,代理可以分为三种,即高度匿名代理、普通匿名代理和透明代理。

(1)高度匿名代理不改变客户机的请求,这样在服务器看来就像有个真正的客户浏览器在访问它,这时客户的真实IP是隐藏的,服务器端不会认为我们使用了代理。

(2)普通匿名代理能隐藏客户机的真实IP,但会改变我们的请求信息,服务器端有可能会认为我们使用了代理。不过使用此种代理时,虽然被访问的网站不能知道你的ip地址,但仍然可以知道你在使用代理,当然某些能够侦测ip的网页仍然可以查到你的ip。

(3)透明代理,它不但改变了我们的请求信息,还会传送真实的IP地址。
三者隐藏使用代理者身份的级别依次为高度匿名代理最隐蔽,其次是普通匿名代理,最差的是透明代理。
 
 
把你找到的代理iP,在你的浏览器里设置一下, 具体可以百度谷歌, 不难.
 
然后用浏览器打开这个网站:
 
http://members.3322.org/dyndns/getip
 
网站返回很简单, 就是你当前的iP地址. 据目前使用那么多的检测iP地址的网站来看,这个网站最准.
 
用代理打开这个网站,如果网站显示的是你代理IP,那么说明你的ip是高度匿名的.
如果网站显示的是有2个ip,那么你的代理是透明的, 第一个ip是你的原始ip,而第二个ip是你用的代理ip.
 

ip代理.PNG

 
 

mongodb中$sum:1 后面的1是什么意思

李魔佛 发表了文章 • 0 个评论 • 10369 次浏览 • 2017-09-05 23:32 • 来自相关话题

源数据:
{
"_id" : "GuqXmAkkARqhBDqhy",
"beatmapset_id" : "342537",
"version" : "MX",
"diff_approach" : "5",
"artist" : "Yousei Teikoku",
"title" : "Kokou no Sousei",
"difficultyrating" : "3.5552737712860107"
}
{
"_id" : "oHLT7KqsB7bztBGvu",
"beatmapset_id" : "342537",
"version" : "HD",
"diff_approach" : "5",
"artist" : "Yousei Teikoku",
"title" : "Kokou no Sousei",
"difficultyrating" : "2.7515676021575928"
}
{
"_id" : "GbotZfrPEwW69FkGD",
"beatmapset_id" : "342537",
"version" : "NM",
"diff_approach" : "5",
"artist" : "Yousei Teikoku",
"title" : "Kokou no Sousei",
"difficultyrating" : "0"
}
 然后运行以下的命令:
 
db.getCollection('dup_case').aggregate(
[
{$group:{
_id:{diff_approach:'$diff_approach'},
count:{$sum:2}
}},
{$match:{count:{$gt:1}}}
]

 
返回的count是6
 
所以
$sum:1 的含义:
如果前面的情况出现一次,就加1, 如果后面$sum:2 那么每次前面条件满足一次就加2
  查看全部
源数据:
{
"_id" : "GuqXmAkkARqhBDqhy",
"beatmapset_id" : "342537",
"version" : "MX",
"diff_approach" : "5",
"artist" : "Yousei Teikoku",
"title" : "Kokou no Sousei",
"difficultyrating" : "3.5552737712860107"
}
{
"_id" : "oHLT7KqsB7bztBGvu",
"beatmapset_id" : "342537",
"version" : "HD",
"diff_approach" : "5",
"artist" : "Yousei Teikoku",
"title" : "Kokou no Sousei",
"difficultyrating" : "2.7515676021575928"
}
{
"_id" : "GbotZfrPEwW69FkGD",
"beatmapset_id" : "342537",
"version" : "NM",
"diff_approach" : "5",
"artist" : "Yousei Teikoku",
"title" : "Kokou no Sousei",
"difficultyrating" : "0"
}

 然后运行以下的命令:
 
db.getCollection('dup_case').aggregate(
[
{$group:{
_id:{diff_approach:'$diff_approach'},
count:{$sum:2}
}},
{$match:{count:{$gt:1}}}
]
)
 
 
返回的count是6
 
所以
$sum:1 的含义:
如果前面的情况出现一次,就加1, 如果后面$sum:2 那么每次前面条件满足一次就加2
 

python print 打印 % 百分号

李魔佛 发表了文章 • 0 个评论 • 16927 次浏览 • 2017-09-05 21:27 • 来自相关话题

记得以前困扰过自己的一个问题.
当时的解决方式是这样的:
 

a = 1
print "a values is ", a, "%"
 
把百分号切割开来.
 
后来才知道,正确显示百分号的方法:
 
 print 'a values is %d%%' %a
 用2个百分号来标示.
 
 
  查看全部
记得以前困扰过自己的一个问题.
当时的解决方式是这样的:
 

a = 1
print "a values is ", a, "%"
 
把百分号切割开来.
 
后来才知道,正确显示百分号的方法:
 
 
print 'a values is %d%%' %a

 用2个百分号来标示.
 
 
 

Python 学习笔记1.2——第三方库安装

sicily02 发表了文章 • 0 个评论 • 2425 次浏览 • 2017-08-27 18:23 • 来自相关话题

电脑配置:windows 64位
python版本:3.6.0
 
一、前往第三方网站下载所需要的包
 
http://www.lfd.uci.edu/~gohlke/pythonlibs/ 
 
二、使用pip安装
 
pip install xxx




  查看全部
电脑配置:windows 64位
python版本:3.6.0
 
一、前往第三方网站下载所需要的包
 
http://www.lfd.uci.edu/~gohlke/pythonlibs/ 
 
二、使用pip安装
 
pip install xxx
5.png

 

python redis 笔记

李魔佛 发表了文章 • 0 个评论 • 2588 次浏览 • 2017-08-24 20:33 • 来自相关话题

刚接触redis,难免会有那么一些坑,新人一定会踩到的。 把自己的坑写出来,让以后新人少踩点吧。 
踩坑也不是什么坏事,不过浪费点时间而已。
 
1. 配置文件redis.config
 
如果你要远程访问你的redis服务器,那么里面有一行你一定要注释掉:

# bind 127.0.0.1
 
 
解释:

#  指定 redis 只接收来自于该 IP 地址的请求,如果不进行设置,那么将处理所有请求
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1
 
 
当时调了半天没连上去,就是被这个参数给害的。
 
2. redis-cli 连接本地redis服务器。 本地服务器端口已经改变。
开始使用redis-cli 127.0.0.1:8888 结果是一直都出错。
然后在某个配置文档看到测试本地端口,使用的命令是 redis-cli -p 8888
不然上面的永远都会连着6379.
 
待续。 不定期更新。 
 
 
 
 
 
 
 
 
  查看全部
刚接触redis,难免会有那么一些坑,新人一定会踩到的。 把自己的坑写出来,让以后新人少踩点吧。 
踩坑也不是什么坏事,不过浪费点时间而已。
 
1. 配置文件redis.config
 
如果你要远程访问你的redis服务器,那么里面有一行你一定要注释掉:

# bind 127.0.0.1
 
 
解释:

#  指定 redis 只接收来自于该 IP 地址的请求,如果不进行设置,那么将处理所有请求
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1
 
 
当时调了半天没连上去,就是被这个参数给害的。
 
2. redis-cli 连接本地redis服务器。 本地服务器端口已经改变。
开始使用redis-cli 127.0.0.1:8888 结果是一直都出错。
然后在某个配置文档看到测试本地端口,使用的命令是 redis-cli -p 8888
不然上面的永远都会连着6379.
 
待续。 不定期更新。 
 
 
 
 
 
 
 
 
 

lxml.etree._ElementUnicodeResult 转为字符

python爬虫李魔佛 发表了文章 • 0 个评论 • 21876 次浏览 • 2017-08-14 15:57 • 来自相关话题

在爬虫过程中,使用的是lxml的xpath查找对应的字段。
 

address=each.xpath('.//address/text()')[0].strip()
 
结果用address与一般的字符进行拼接时,总是出现
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
 
这种错误。
 
主要因为python2的蛋疼的编码原因。
 
解决办法:
根据lxml的官方文档:http://lxml.de/api/lxml.etree._ElementUnicodeResult-class.html
 

object --+ | basestring --+ | unicode --+ | _ElementUnicodeResult
 
_ElementUnicodeResult 是unicode的一个子类。
 
那么可以直接将它转为unicode
 
address.encode('utf-8') 就可以了。
  查看全部
在爬虫过程中,使用的是lxml的xpath查找对应的字段。
 

address=each.xpath('.//address/text()')[0].strip()
 
结果用address与一般的字符进行拼接时,总是出现
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
 
这种错误。
 
主要因为python2的蛋疼的编码原因。
 
解决办法:
根据lxml的官方文档:http://lxml.de/api/lxml.etree._ElementUnicodeResult-class.html
 

object --+ | basestring --+ | unicode --+ | _ElementUnicodeResult
 
_ElementUnicodeResult 是unicode的一个子类。
 
那么可以直接将它转为unicode
 
address.encode('utf-8') 就可以了。
 

修改python的默认最大递归层数

李魔佛 发表了文章 • 0 个评论 • 5317 次浏览 • 2017-08-10 16:00 • 来自相关话题

python里面为了性能,默认的递归次数不能超过1000次。
 
运行下面的代码:
def recursion(n):
if(n <= 0):
print n
return
print n
recursion(n - 1)

if __name__ == "__main__":
recursion(1200)
返回下面的错误:
 
  File "C:/Git/base_function/resursion_usage.py", line 7, in recursion
    recursion(n - 1)
RuntimeError: maximum recursion depth exceeded
 
解决办法: 修改python默认的递归层数。
在程序开头的地方添加以下语句:
 
import sys
sys.setrecursionlimit(1500)
然后再次运行,就不会有上面的错误信息了。
  查看全部
python里面为了性能,默认的递归次数不能超过1000次。
 
运行下面的代码:
def recursion(n): 
if(n <= 0):
print n
return
print n
recursion(n - 1)

if __name__ == "__main__":
recursion(1200)

返回下面的错误:
 
  File "C:/Git/base_function/resursion_usage.py", line 7, in recursion
    recursion(n - 1)
RuntimeError: maximum recursion depth exceeded
 
解决办法: 修改python默认的递归层数。
在程序开头的地方添加以下语句:
 
import sys
sys.setrecursionlimit(1500)

然后再次运行,就不会有上面的错误信息了。
 

python matplotlib 中的plot legend的用法

李魔佛 发表了文章 • 0 个评论 • 22878 次浏览 • 2017-07-13 11:59 • 来自相关话题

官方有链接说明:https://matplotlib.org/users/legend_guide.html
不过对于大部分人来说,英文教程,加上上面的例子有点晦涩。
 
所以以个人的理解,简单地用代码介绍下。 import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)
print x
fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
#ax.plot(x, i * x, label='y=%dx' %i)
ax.plot(x, i * x, label='$y = %ix$' % i)

ax.legend()

plt.show()
 
运行上面的代码后,得到的结果是:
 





 
如果把那句legend() 的语句去掉,那么图形上的图例也就会消失了。
 
所以legend()的主要只用就是用于在图上标明一个图例,用于说明每条曲线的文字显示。 你也可以把图例控制在左边,右边,底下等等。
 
 
实际使用中,legend()有一个loc参数,用于控制图例的位置。 比如 plot.legend(loc=2) , 这个位置就是4象项中的第二象项,也就是左上角。 loc可以为1,2,3,4 这四个数字。
原文连接:
http://30daydo.com/article/215
转载请注明出处 查看全部
官方有链接说明:https://matplotlib.org/users/legend_guide.html
不过对于大部分人来说,英文教程,加上上面的例子有点晦涩。
 
所以以个人的理解,简单地用代码介绍下。
    import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)
print x
fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
#ax.plot(x, i * x, label='y=%dx' %i)
ax.plot(x, i * x, label='$y = %ix$' % i)

ax.legend()

plt.show()

 
运行上面的代码后,得到的结果是:
 

legend.PNG

 
如果把那句legend() 的语句去掉,那么图形上的图例也就会消失了。
 
所以legend()的主要只用就是用于在图上标明一个图例,用于说明每条曲线的文字显示。 你也可以把图例控制在左边,右边,底下等等。
 
 
实际使用中,legend()有一个loc参数,用于控制图例的位置。 比如 plot.legend(loc=2) , 这个位置就是4象项中的第二象项,也就是左上角。 loc可以为1,2,3,4 这四个数字。
原文连接:
http://30daydo.com/article/215
转载请注明出处

为什么使用dataframe自带的plot函数绘图 没有输出图像?

李魔佛 发表了文章 • 0 个评论 • 8512 次浏览 • 2017-07-11 18:32 • 来自相关话题

比如:
df=pd.read_csv('LoanStats_2017Q1.csv',header=0)
print df.head(10)
print df.describe()

analysis_columns = ['issue_d','term','int_rate','emp_title','grade','home_ownership','verification_status','purpose','loan_amnt','total_pymnt','out_prncp','total_rec_int','total_rec_prncp','installment','annual_inc','dti','fico_range_low','fico_range_high','last_fico_range_low','last_fico_range_high','open_acc','loan_status','delinq_amnt','acc_now_delinq','tot_coll_amt']
deal_data = df.loc[:,analysis_columns]
print deal_data
deal_data.groupby('issue_d').agg({'loan_amnt':'sum'}).plot(kind="bar")
deal_data.groupby('issue_d').agg({'issue_d':'count'}).plot(kind = 'bar')
在pycharm中程序运行完了就直接退出,没有输出任何的图像。
 
然后看了下源码后,需要在后面手工添加一句 plt.show()
 
这样就能够正常显示图像了。 查看全部
比如:
    df=pd.read_csv('LoanStats_2017Q1.csv',header=0)
print df.head(10)
print df.describe()

analysis_columns = ['issue_d','term','int_rate','emp_title','grade','home_ownership','verification_status','purpose','loan_amnt','total_pymnt','out_prncp','total_rec_int','total_rec_prncp','installment','annual_inc','dti','fico_range_low','fico_range_high','last_fico_range_low','last_fico_range_high','open_acc','loan_status','delinq_amnt','acc_now_delinq','tot_coll_amt']
deal_data = df.loc[:,analysis_columns]
print deal_data
deal_data.groupby('issue_d').agg({'loan_amnt':'sum'}).plot(kind="bar")
deal_data.groupby('issue_d').agg({'issue_d':'count'}).plot(kind = 'bar')

在pycharm中程序运行完了就直接退出,没有输出任何的图像。
 
然后看了下源码后,需要在后面手工添加一句 plt.show()
 
这样就能够正常显示图像了。

numpy/dataframe 中cumsum 的用法

李魔佛 发表了文章 • 0 个评论 • 6862 次浏览 • 2017-07-11 17:54 • 来自相关话题

用途:cumsum                 样本值的累计和
 
例子:
 
x=np.arange(101)
y=x.cumsum()
print y
print len(y)
x为一个0到100的array, 那么对这个array进行cumsum操作后
y现在的值为:
 
[ 0 1 3 6 10 15 21 28 36 45 55 66 78 91 105
120 136 153 171 190 210 231 253 276 300 325 351 378 406 435
465 496 528 561 595 630 666 703 741 780 820 861 903 946 990
1035 1081 1128 1176 1225 1275 1326 1378 1431 1485 1540 1596 1653 1711 1770
1830 1891 1953 2016 2080 2145 2211 2278 2346 2415 2485 2556 2628 2701 2775
2850 2926 3003 3081 3160 3240 3321 3403 3486 3570 3655 3741 3828 3916 4005
4095 4186 4278 4371 4465 4560 4656 4753 4851 4950 5050]
 
从结果很明显看到 cumsum是将样本逐渐累加,第一个是0,第二个是0+1,第三个是0+1+2,所以第三个是3,第4个是0+1+2+3=6,如此类推,最后一个就是这101个数的累加和,5050
 
  查看全部
用途:cumsum                 样本值的累计和
 
例子:
 
    x=np.arange(101)
y=x.cumsum()
print y
print len(y)

x为一个0到100的array, 那么对这个array进行cumsum操作后
y现在的值为:
 
[   0    1    3    6   10   15   21   28   36   45   55   66   78   91  105
120 136 153 171 190 210 231 253 276 300 325 351 378 406 435
465 496 528 561 595 630 666 703 741 780 820 861 903 946 990
1035 1081 1128 1176 1225 1275 1326 1378 1431 1485 1540 1596 1653 1711 1770
1830 1891 1953 2016 2080 2145 2211 2278 2346 2415 2485 2556 2628 2701 2775
2850 2926 3003 3081 3160 3240 3321 3403 3486 3570 3655 3741 3828 3916 4005
4095 4186 4278 4371 4465 4560 4656 4753 4851 4950 5050]

 
从结果很明显看到 cumsum是将样本逐渐累加,第一个是0,第二个是0+1,第三个是0+1+2,所以第三个是3,第4个是0+1+2+3=6,如此类推,最后一个就是这101个数的累加和,5050
 
 

python uiautomator 安卓自动化测试

再坚持一下就好了 发表了文章 • 0 个评论 • 4634 次浏览 • 2017-06-18 16:46 • 来自相关话题

本教程使用的是win7 系统 - python 2.7
1. 安装uiautomator 同pip install uiautomator
 时确保你的手机连上电脑后,adb可以正常使用, 在命令行运行adb devices,能够有设备的id输出

2. 获取手机的基本信息:
导入uiautomator包: 

from uiautomator import device as d

这样子就可以使用d操作手机,获取手机信息。info= d.info
print info
print type(info)
for i in info:
print i,info[i]
输出的内容:
 {u'displayRotation': 0, u'displaySizeDpY': 640, u'displaySizeDpX': 360, u'screenOn': False, u'currentPackageName': u'com.smartisanos.keyguard', u'productName': u'icesky_msm8992', u'displayWidth': 1080, u'sdkInt': 22, u'displayHeight': 1920, u'naturalOrientation': True}
<type 'dict'>
displayRotation 0
displaySizeDpY 640
displaySizeDpX 360
screenOn False
currentPackageName com.smartisanos.keyguard
productName icesky_msm8992
displayWidth 1080
sdkInt 22
displayHeight 1920
naturalOrientation True

手机的分辨率
displayWidth 1080
displayHeight 1920

当前打开的包名: currentPackageName com.smartisanos.keyguard
 
3.d.press.home()
result=d(text=u'设置').wait.exists(timeout=10000)
#单位是毫秒, 如果timeout还没有找到,就返回false
print "next"
if result:
print "You press setting"
else:
print "You don't touch any thing"

打开home主界面,然后查看时候有设置这个选项或者图标文字。
d(text=u'设置').wait.exists(timeout=10000)

如果在10s内找到这个字符,那么这一行就返回True, 否则返回False
 
  查看全部
本教程使用的是win7 系统 - python 2.7
1. 安装uiautomator 同
pip install uiautomator

 时确保你的手机连上电脑后,adb可以正常使用, 在命令行运行adb devices,能够有设备的id输出

2. 获取手机的基本信息:
导入uiautomator包: 

from uiautomator import device as d

这样子就可以使用d操作手机,获取手机信息。
info= d.info
print info
print type(info)
for i in info:
print i,info[i]

输出的内容:
 
{u'displayRotation': 0, u'displaySizeDpY': 640, u'displaySizeDpX': 360, u'screenOn': False, u'currentPackageName': u'com.smartisanos.keyguard', u'productName': u'icesky_msm8992', u'displayWidth': 1080, u'sdkInt': 22, u'displayHeight': 1920, u'naturalOrientation': True}
<type 'dict'>
displayRotation 0
displaySizeDpY 640
displaySizeDpX 360
screenOn False
currentPackageName com.smartisanos.keyguard
productName icesky_msm8992
displayWidth 1080
sdkInt 22
displayHeight 1920
naturalOrientation True


手机的分辨率
displayWidth 1080
displayHeight 1920

当前打开的包名: currentPackageName com.smartisanos.keyguard
 
3.
d.press.home()
result=d(text=u'设置').wait.exists(timeout=10000)
#单位是毫秒, 如果timeout还没有找到,就返回false
print "next"
if result:
print "You press setting"
else:
print "You don't touch any thing"


打开home主界面,然后查看时候有设置这个选项或者图标文字。
d(text=u'设置').wait.exists(timeout=10000)

如果在10s内找到这个字符,那么这一行就返回True, 否则返回False
 
 

dataframe读取excel文件第一行是列名如何跳过

李魔佛 发表了文章 • 0 个评论 • 13348 次浏览 • 2017-06-13 01:15 • 来自相关话题

比如数据如下:
 股票代码 股票简称 涨跌幅(%) 现价(元) 收盘价:前复权(元) 区间涨跌幅:前复权(%) 交易状态
2016.07.13 2016.07.13 2016.07.13
300501.SZ 海顺新材 10.00 144.65 131.50 3.06 交易
300384.SZ 三联虹普 -0.67 57.63 58.02 5.97 交易
300506.SZ 名家汇 5.98 60.98 57.54 5.52 交易
002572.SZ 索菲亚 1.03 56.80 56.22 -0.65 交易
600419.SH 天润乳业 4.66 57.10 54.56 0.06 交易
300494.SZ 盛天网络 4.86 54.19 51.68 2.64 交易
300369.SZ 绿盟科技 2.36 45.50 44.45 -0.96 交易
002113.SZ 天润数娱 -1.89 43.55 44.39 7.14 交易
002190.SZ 成飞集成 10.01 47.17 42.88 10.01 交易
600391.SH 成发科技 3.39 43.56 42.13 1.54 交易
002699.SZ 美盛文化 3.25 40.99 39.70 9.97 交易
603027.SH 千禾味业 3.70 40.39 38.95 -1.77 交易
600893.SH 中航动力 2.03 39.29 38.51 0.44 交易
603005.SH 晶方科技 4.34 40.16 38.49 2.89 交易
300339.SZ 润和软件 2.50 36.98 36.08 1.32 交易
300246.SZ 宝莱特 3.92 37.42 36.01 -0.91 交易
002368.SZ 太极股份 4.23 37.50 35.98 1.75 交易
000555.SZ 神州信息 0.35 34.66 34.54 -0.75 交易
002745.SZ 木林森 9.15 37.10 33.99 -0.23 交易
002589.SZ 瑞康医药 -1.49 33.00 33.50 4.82 交易
002007.SZ 华兰生物 3.31 33.36 32.29 -0.89 交易
002456.SZ 欧菲光 0.32 31.60 31.50 7.88 交易
002759.SZ 天际股份 9.99 34.01 30.92 0.00 重大事项,停牌自2016-07-12起连续停牌


那么怎样不把第一行的数据读入呢? 或者说把第一行的数据给忽略掉呢?
 sheet1 = pd.read_excel('test.xls', header=0, skiprows=[0] ) 
 
原文链接:http://30daydo.com/article/209
欢迎转载,转载请注明出处。 查看全部
比如数据如下:
 
股票代码	股票简称	涨跌幅(%)	现价(元)	收盘价:前复权(元)	区间涨跌幅:前复权(%)	交易状态
2016.07.13 2016.07.13 2016.07.13
300501.SZ 海顺新材 10.00 144.65 131.50 3.06 交易
300384.SZ 三联虹普 -0.67 57.63 58.02 5.97 交易
300506.SZ 名家汇 5.98 60.98 57.54 5.52 交易
002572.SZ 索菲亚 1.03 56.80 56.22 -0.65 交易
600419.SH 天润乳业 4.66 57.10 54.56 0.06 交易
300494.SZ 盛天网络 4.86 54.19 51.68 2.64 交易
300369.SZ 绿盟科技 2.36 45.50 44.45 -0.96 交易
002113.SZ 天润数娱 -1.89 43.55 44.39 7.14 交易
002190.SZ 成飞集成 10.01 47.17 42.88 10.01 交易
600391.SH 成发科技 3.39 43.56 42.13 1.54 交易
002699.SZ 美盛文化 3.25 40.99 39.70 9.97 交易
603027.SH 千禾味业 3.70 40.39 38.95 -1.77 交易
600893.SH 中航动力 2.03 39.29 38.51 0.44 交易
603005.SH 晶方科技 4.34 40.16 38.49 2.89 交易
300339.SZ 润和软件 2.50 36.98 36.08 1.32 交易
300246.SZ 宝莱特 3.92 37.42 36.01 -0.91 交易
002368.SZ 太极股份 4.23 37.50 35.98 1.75 交易
000555.SZ 神州信息 0.35 34.66 34.54 -0.75 交易
002745.SZ 木林森 9.15 37.10 33.99 -0.23 交易
002589.SZ 瑞康医药 -1.49 33.00 33.50 4.82 交易
002007.SZ 华兰生物 3.31 33.36 32.29 -0.89 交易
002456.SZ 欧菲光 0.32 31.60 31.50 7.88 交易
002759.SZ 天际股份 9.99 34.01 30.92 0.00 重大事项,停牌自2016-07-12起连续停牌


那么怎样不把第一行的数据读入呢? 或者说把第一行的数据给忽略掉呢?
 
sheet1 = pd.read_excel('test.xls', header=0, skiprows=[0] )
 
 
原文链接:http://30daydo.com/article/209
欢迎转载,转载请注明出处。

ImportError: No module named _tkinter

李魔佛 发表了文章 • 0 个评论 • 6519 次浏览 • 2017-05-28 21:33 • 来自相关话题

ImportError: No module named _tkinter, please install the python-tk package ubuntu运行tkinter错误
 
 这是由于Python的版本没有包含tkinter的模块,只需要把tk的package安装就可以了。 一般在Linux才出现,windows版本一般已经包含了tkinter模块。

apt-get install python-tk 查看全部
ImportError: No module named _tkinter, please install the python-tk package ubuntu运行tkinter错误
 
 这是由于Python的版本没有包含tkinter的模块,只需要把tk的package安装就可以了。 一般在Linux才出现,windows版本一般已经包含了tkinter模块。

apt-get install python-tk

破解安卓锁屏图案

李魔佛 发表了文章 • 0 个评论 • 11127 次浏览 • 2017-05-23 23:56 • 来自相关话题

http://30daydo.com/article/194
 目前成功的有2种方法:
 
方法1: 暴力,快速。 只需几秒钟的时间就可以了。 不过前提需要你的手机又root权限。
 
具体操作: ADB连接手机,然后运行“adb rm /data/system/gesture.key”删除掉gesture.key文件,此时图形锁就失效了,随意画一下就能解锁。
 
方法2: 速度慢,但是可以还原你的锁屏图案。 这个方法同样需要root





 
 # -*- coding: cp936 -*-
import itertools
import hashlib
import time
import os

#调用cmd,ADB连接到手机,读取SHA1加密后的字符串
os.system("adb pull /data/system/gesture.key gesture.key")
time.sleep(5)
f=open('gesture.key','r')
pswd=f.readline()
f.close()
pswd_hex=pswd.encode('hex')
print '加密后的密码为:%s'%pswd_hex

#生成解锁序列,得到['00','01','02','03','04','05','06','07','08']
matrix=
for i in range(0,9):
str_temp = '0'+str(i)
matrix.append(str_temp)

#将00——08的字符进行排列,至少取4个数排列,最多全部进行排列

min_num=4
max_num=len(matrix)

for num in range(min_num,max_num+1):#从04 -> 08
iter1 = itertools.permutations(matrix,num)#从9个数字中挑出n个进行排列
list_m=
list_m.append(list(iter1))#将生成的排列全部存放到 list_m 列表中
for el in list_m[0]:#遍历这n个数字的全部排列
strlist=''.join(el)#将list转换成str。[00,03,06,07,08]-->0003060708
strlist_sha1 = hashlib.sha1(strlist.decode('hex')).hexdigest()#将字符串进行SHA1加密
if pswd_hex==strlist_sha1:#将手机文件里的字符串与加密字符串进行对比
print '解锁密码为:',strlist
原理分析
 
首先科普一下,安卓手机是如何标记这9个点的。通过阅读安卓系统源码可知,每个点都有其编号,组成了一个3×3的矩阵,形如:
 00 01 02
03 04 05
06 07 08
假如设定解锁图形为一个“L”形,如图:
 





 
那么这几个点的排列顺序是这样的:00 03 06 07 08。系统就记下来了这一串数字,然后将这一串数字(以十六进制的方式)进行SHA1加密,存储在了手机里的/data/system/gesture.key 文件中
 
WinHex等十六进制编辑程序打开gesture.key,会发现文件内是SHA1加密过的字符串:c8c0b24a15dc8bbfd411427973574695230458f0
 
当你下次解锁的时候,系统就对比你画的图案,看对应的数字串是不是0003060708对应的加密结果。如果是,就解锁;不是就继续保持锁定。那么,如果穷举所有的数字串排列,会有多少呢?联想到高中的阶乘,如果用4个点做解锁图形的话,就是9x8x7x6=3024种可能性,那5个点就是15120,6个点的话60480,7个点181440,8个点362880,9个点362880。总共是985824种可能性‍‍(但这么计算并不严密,因为同一条直线上的点只能和他们相邻的点相连)‍‍。

满打满算,也不到985824种可能性。乍一看很大,但在计算机面前,穷举出来这些东西用不了几秒钟。
 
当你下次解锁的时候,系统就对比你画的图案,看对应的数字串是不是0003060708对应的加密结果。如果是,就解锁;不是就继续保持锁定。那么,如果穷举所有的数字串排列,会有多少呢?联想到高中的阶乘,如果用4个点做解锁图形的话,就是9x8x7x6=3024种可能性,那5个点就是15120,6个点的话60480,7个点181440,8个点362880,9个点362880。总共是985824种可能性‍‍(但这么计算并不严密,因为同一条直线上的点只能和他们相邻的点相连)‍‍。

满打满算,也不到985824种可能性。乍一看很大,但在计算机面前,穷举出来这些东西用不了几秒钟。
 
 
  查看全部
http://30daydo.com/article/194
 目前成功的有2种方法:
 
方法1: 暴力,快速。 只需几秒钟的时间就可以了。 不过前提需要你的手机又root权限。
 
具体操作: ADB连接手机,然后运行“adb rm /data/system/gesture.key”删除掉gesture.key文件,此时图形锁就失效了,随意画一下就能解锁。
 
方法2: 速度慢,但是可以还原你的锁屏图案。 这个方法同样需要root

14255226989905.jpg

 
 
# -*- coding: cp936 -*-
import itertools
import hashlib
import time
import os

#调用cmd,ADB连接到手机,读取SHA1加密后的字符串
os.system("adb pull /data/system/gesture.key gesture.key")
time.sleep(5)
f=open('gesture.key','r')
pswd=f.readline()
f.close()
pswd_hex=pswd.encode('hex')
print '加密后的密码为:%s'%pswd_hex

#生成解锁序列,得到['00','01','02','03','04','05','06','07','08']
matrix=
for i in range(0,9):
str_temp = '0'+str(i)
matrix.append(str_temp)

#将00——08的字符进行排列,至少取4个数排列,最多全部进行排列

min_num=4
max_num=len(matrix)

for num in range(min_num,max_num+1):#从04 -> 08
iter1 = itertools.permutations(matrix,num)#从9个数字中挑出n个进行排列
list_m=
list_m.append(list(iter1))#将生成的排列全部存放到 list_m 列表中
for el in list_m[0]:#遍历这n个数字的全部排列
strlist=''.join(el)#将list转换成str。[00,03,06,07,08]-->0003060708
strlist_sha1 = hashlib.sha1(strlist.decode('hex')).hexdigest()#将字符串进行SHA1加密
if pswd_hex==strlist_sha1:#将手机文件里的字符串与加密字符串进行对比
print '解锁密码为:',strlist

原理分析
 
首先科普一下,安卓手机是如何标记这9个点的。通过阅读安卓系统源码可知,每个点都有其编号,组成了一个3×3的矩阵,形如:
 
00 01 02
03 04 05
06 07 08

假如设定解锁图形为一个“L”形,如图:
 

77681425522640.png

 
那么这几个点的排列顺序是这样的:00 03 06 07 08。系统就记下来了这一串数字,然后将这一串数字(以十六进制的方式)进行SHA1加密,存储在了手机里的/data/system/gesture.key 文件中
 
WinHex等十六进制编辑程序打开gesture.key,会发现文件内是SHA1加密过的字符串:c8c0b24a15dc8bbfd411427973574695230458f0
 
当你下次解锁的时候,系统就对比你画的图案,看对应的数字串是不是0003060708对应的加密结果。如果是,就解锁;不是就继续保持锁定。那么,如果穷举所有的数字串排列,会有多少呢?联想到高中的阶乘,如果用4个点做解锁图形的话,就是9x8x7x6=3024种可能性,那5个点就是15120,6个点的话60480,7个点181440,8个点362880,9个点362880。总共是985824种可能性‍‍(但这么计算并不严密,因为同一条直线上的点只能和他们相邻的点相连)‍‍。

满打满算,也不到985824种可能性。乍一看很大,但在计算机面前,穷举出来这些东西用不了几秒钟。
 
当你下次解锁的时候,系统就对比你画的图案,看对应的数字串是不是0003060708对应的加密结果。如果是,就解锁;不是就继续保持锁定。那么,如果穷举所有的数字串排列,会有多少呢?联想到高中的阶乘,如果用4个点做解锁图形的话,就是9x8x7x6=3024种可能性,那5个点就是15120,6个点的话60480,7个点181440,8个点362880,9个点362880。总共是985824种可能性‍‍(但这么计算并不严密,因为同一条直线上的点只能和他们相邻的点相连)‍‍。

满打满算,也不到985824种可能性。乍一看很大,但在计算机面前,穷举出来这些东西用不了几秒钟。
 
 
 

This probably means that Tcl wasn't installed properly [matplotlib][win7]

回复

李魔佛 发起了问题 • 1 人关注 • 0 个回复 • 10330 次浏览 • 2017-05-05 17:25 • 来自相关话题

python 求2个list列表的相关系数

李魔佛 发表了文章 • 0 个评论 • 45522 次浏览 • 2017-04-30 23:34 • 来自相关话题

相关系数的一些介绍:相关系数用来表示两个数据是否具有相关性,比如人每天吃饭的饭量和他的体重具有正相关系,也就是吃的饭量越多,体重会越重。 当然也会有例外,所以这个相关系数不会为1. 如果为1就是说明完全的正相关。
比如 c=[2,4,6,8,10,12,14,16,18] ,和d=[4,8,12,20,24,28,32,36], 这两组数据,相关系数为1,因为二者的数据都在同一条直线上。 存在必然的因果关系。
 





 
其计算公式为:





 
 
实际上python的中pandas已经提供了很简单的内置函数,可以自己计算这个相关系数。 在《python数据分析》这本书就有,不过网上查到的资料就比较少。
 
参考代码: c=[2,4,6,8,10,12,14,16,18]
d= [i*2 for i in c]
print d
s1=Series(c) #转为series类型
s2=Series(d)
corr=s1.corr(s2) #计算相关系数
print corrcorr()就是计算相关系数的函数。
 
上面的例子中,计算出的corr的值为1,如果修改一下d的某个值,比如 d[0]=3 把d的第一个值改为3,那么相关系数就不为1,但是他的相关系数为0.987503379952, 也差不多接近1. 说明这两组数据也是相关性很大的。c=[2,4,6,8,10,12,14,16,18]
d= [i*2 for i in c]
print d
d[0]=3 # 修改d[0]的值
s1=Series(c) #转为series类型
s2=Series(d)
corr=s1.corr(s2) #计算相关系数
print corr 
原创地址:http://www.30daydo.com/article/178​
欢迎转载,请注明出处。
 
  查看全部
相关系数的一些介绍:相关系数用来表示两个数据是否具有相关性,比如人每天吃饭的饭量和他的体重具有正相关系,也就是吃的饭量越多,体重会越重。 当然也会有例外,所以这个相关系数不会为1. 如果为1就是说明完全的正相关。
比如 c=[2,4,6,8,10,12,14,16,18] ,和d=[4,8,12,20,24,28,32,36], 这两组数据,相关系数为1,因为二者的数据都在同一条直线上。 存在必然的因果关系。
 

相关系数.png

 
其计算公式为:

01300000432684142233939909878_s.jpg

 
 
实际上python的中pandas已经提供了很简单的内置函数,可以自己计算这个相关系数。 在《python数据分析》这本书就有,不过网上查到的资料就比较少。
 
参考代码:
    c=[2,4,6,8,10,12,14,16,18]
d= [i*2 for i in c]
print d
s1=Series(c) #转为series类型
s2=Series(d)
corr=s1.corr(s2) #计算相关系数
print corr
corr()就是计算相关系数的函数。
 
上面的例子中,计算出的corr的值为1,如果修改一下d的某个值,比如 d[0]=3 把d的第一个值改为3,那么相关系数就不为1,但是他的相关系数为0.987503379952, 也差不多接近1. 说明这两组数据也是相关性很大的。
c=[2,4,6,8,10,12,14,16,18]
d= [i*2 for i in c]
print d
d[0]=3 # 修改d[0]的值
s1=Series(c) #转为series类型
s2=Series(d)
corr=s1.corr(s2) #计算相关系数
print corr
 
原创地址:http://www.30daydo.com/article/178​
欢迎转载,请注明出处。
 
 

numpy 中的ndarray类型转为list类型 / list转为ndarray类型

李魔佛 发表了文章 • 0 个评论 • 35578 次浏览 • 2017-04-22 22:50 • 来自相关话题

numpy的ndarry的类型是这样的[ 1  2 3 4  5] 中间是没有逗号的。实际上ndarray和np.array是一样的。用np.array([1,2,3]) 就可以生成ndarray.
 
而python的基本类型list 是[ 1  ,2, 3,4,  5]这样的。
 
那么二者可以互换
 
ndarray转换为list d=np.array([1, 2, 3,4,5 ])
print d
e=d.tolist()
print e 或者直接调用list()
 d=np.array([1, 2, 3,4,5 ])
print d
e=list(d)
print e
而list转为ndarry就依照上面的代码就可以了lst=[1, 2, 3,4,5 ]
d=np.array(lst)
原创地址:http://www.30daydo.com/article/174
转载请注明出处 查看全部
numpy的ndarry的类型是这样的[ 1  2 3 4  5] 中间是没有逗号的。实际上ndarray和np.array是一样的。用np.array([1,2,3]) 就可以生成ndarray.
 
而python的基本类型list 是[ 1  ,2, 3,4,  5]这样的。
 
那么二者可以互换
 
ndarray转换为list 
d=np.array([1, 2, 3,4,5 ])
print d
e=d.tolist()
print e
 或者直接调用list()
 
d=np.array([1, 2, 3,4,5 ])
print d
e=list(d)
print e

而list转为ndarry就依照上面的代码就可以了
lst=[1, 2, 3,4,5 ]
d=np.array(lst)

原创地址:http://www.30daydo.com/article/174
转载请注明出处

Dataframe的数据print输出 显示为...省略号

李魔佛 发表了文章 • 0 个评论 • 9754 次浏览 • 2017-04-12 01:08 • 来自相关话题

例如: def get_achievement(self):
fc=ts.forecast_data(2016,4)
print fc 
上面这个简单的代码意思是获取已经发布的2016年第4季度的业绩预告的上市公司。
 
默认输出的结果是:





 
 
中间多了个省略号,就是中间若干的数据因为太多而没有被显示。 那么要怎样才能正常显示所有数据呢???
 
查看了pandas的官方文档。
 





 
 
pandas.set_option() 可以设置pandas相关的参数,从而改变默认参数。 打印pandas数据事,默认是输出100行,多的话会输出....省略号。
 
那么可以添加: pandas.set_option('display.max_rows',None)
这样就可以显示全部数据:
 
def get_achievement(self):

fc=ts.forecast_data(2016,4)
pandas.set_option('display.max_rows',None)
print fc
  查看全部
例如:
    def get_achievement(self):
fc=ts.forecast_data(2016,4)
print fc
 
上面这个简单的代码意思是获取已经发布的2016年第4季度的业绩预告的上市公司。
 
默认输出的结果是:

pandas省略号.PNG

 
 
中间多了个省略号,就是中间若干的数据因为太多而没有被显示。 那么要怎样才能正常显示所有数据呢???
 
查看了pandas的官方文档。
 

max_row.PNG

 
 
pandas.set_option() 可以设置pandas相关的参数,从而改变默认参数。 打印pandas数据事,默认是输出100行,多的话会输出....省略号。
 
那么可以添加: pandas.set_option('display.max_rows',None)
这样就可以显示全部数据:
 
    def get_achievement(self):

fc=ts.forecast_data(2016,4)
pandas.set_option('display.max_rows',None)
print fc

 

requests 使用默认 cookies

python爬虫李魔佛 发表了文章 • 0 个评论 • 6010 次浏览 • 2017-03-17 01:41 • 来自相关话题

对于一些网站,为了防止爬虫,必须要有cookies信息,header中的cookies字段不能空。
使用requests库的时候,可以初始化一次cookies信息,后面的回话就能够一直用这个cookies了。session=requests.session()
#先创建一个seession

s=session.get('http://xueqiu.com',headers=self.headers)
#随意建立一个访问雪球的session,此时的session就自带了雪球的cookies

url='https://xueqiu.com/snowmart/push/stocks.json?product_id=19&page=3&count=5'
headers['Referer']='https://xueqiu.com/strategy/19'
headers['X-Requested-With']='XMLHttpRequest'
headers['DNT']='1'

data={'product_id':19,'page':3,'count':5}

resp=session.get(url,headers=self.headers,params=data).text
#如果这里用的request.get的话,就不能获取到网页返回的正确内容
print resp 这里需要注意的是,第一次

s=session.get('http://xueqiu.com',headers=self.headers) #随意建立一个访问雪球的session,此时的session就自带了雪球的cookies
 
是必须的,如果没有只一次正常访问,cookies就不能保存下来供下一次正常使用。
 
 
2017-3-28 更新
一般来说,除非是为了每天定期跑的或者破解他人密码这些,可以不用管他们的登录问题,可以很直接的在浏览器中,把你自己账号的cookie信息写进到request的header里面,完全可以访问。
 
所以一旦cookie被别人获取了,他们就可以构造数据,去获取你账号的相关信息。 (cookie应该和你的电脑硬件没关系的吧? 因为我曾经在几台机器上用同一个cookie获取我登录了的账号,也是没有问题的)
 
举个栗子:

def csdn():
session=requests.session()
header={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36'}
url='[url]http://msg.csdn.net/'[/url] header['Cookie']='uuid_tt_dd=-5697318013068753627_20160111; _ga=GA1.2.795042232.1452766190; _message_m=quvq2wle24wa4awe UserInfo=zMhiNgesgIlEBQ3TOqLCtx4nUI360IIq3ciBzg4EKH%2FW8mSpTANpu5cTlRFLj2Tqh%2FZzQr2rNqDtT1SZz%2Be2%2FpDkGoQxDK3IVUZXvwZ%2FEP1I4UTg6MoZkH7LDO3sjrJJ; UserNick=%E9%87%8D%E5%A4%8D%E7%9A%84%E7%94%9F%E6%B4%BB; AU=0F1; UD=%E8%AE%B0%E5%BD%95%E8%87%AA%E5%AD%A6%E7%9A%84%E5%8E%86%E7%A8%8B+%E5%88%83%E8%8D%; BT=1490707396344; access-token=c2e12bff-5b27-4a91-953b-448ff6f6beac; _csdn_notify_admin_session=VE41a0d3TitrVGY2bGtXY09pZENwR1lHenhUU1NVaWc1b04wL1I3dCtDQVdadWpjMXBzdGRJL0RZR04wYldvZDBhTU96b2oycVVKeVI1UEVyUHFKbG1yNnB2b2pHRWVnWG1uc2JMM2R3YWthakRyTXZNaEpVU1NtUy9zQUJrNjd3R2lpbG5PK0paMnlyc1dyK0lTZUtRPT0tLXlPQUE1QzF5UmhDNjEvSFdtRFlQS2c9PQ%3D%3D--4569c5a32916dcf969a8b7e007c37abeb90be4f3; dc_tos=onj1dg; dc_session_id=1490707393375; Hm_lvt_6bcd52f51e9b3dce32bec4a3997715ac=1490024083,1490024559,1490374375,1490707368; Hm_lpvt_6bcd52f51e9b3dce32bec4a3997715ac=1490707638' header['Cache-Control']='max-age=0'
header['Host']='msg.csdn.net'
header['Referer']='http://blog.csdn.net/username'
resp=requests.get(url,headers=header)
print resp.text
 
上面这段代码,只要你改一下cookie和 Refer 的连接,改成你自己的用户名。 你就可以访问你的csdn的消息,也就是别人在你的csdn博客访问的的留言,评论。
 
只是这个cookie只能在某个时间段生效,也就是存活期大概就一个星期左右。

 抓包技术过硬,何须模拟登陆?
 
 
http://30daydo.com/publish/article/155
  查看全部
对于一些网站,为了防止爬虫,必须要有cookies信息,header中的cookies字段不能空。
使用requests库的时候,可以初始化一次cookies信息,后面的回话就能够一直用这个cookies了。
session=requests.session()
#先创建一个seession

s=session.get('http://xueqiu.com',headers=self.headers)
#随意建立一个访问雪球的session,此时的session就自带了雪球的cookies

url='https://xueqiu.com/snowmart/push/stocks.json?product_id=19&page=3&count=5'
headers['Referer']='https://xueqiu.com/strategy/19'
headers['X-Requested-With']='XMLHttpRequest'
headers['DNT']='1'

data={'product_id':19,'page':3,'count':5}

resp=session.get(url,headers=self.headers,params=data).text
#如果这里用的request.get的话,就不能获取到网页返回的正确内容
print resp
 这里需要注意的是,第一次

s=session.get('http://xueqiu.com',headers=self.headers) #随意建立一个访问雪球的session,此时的session就自带了雪球的cookies
 
是必须的,如果没有只一次正常访问,cookies就不能保存下来供下一次正常使用。
 
 
2017-3-28 更新
一般来说,除非是为了每天定期跑的或者破解他人密码这些,可以不用管他们的登录问题,可以很直接的在浏览器中,把你自己账号的cookie信息写进到request的header里面,完全可以访问。
 
所以一旦cookie被别人获取了,他们就可以构造数据,去获取你账号的相关信息。 (cookie应该和你的电脑硬件没关系的吧? 因为我曾经在几台机器上用同一个cookie获取我登录了的账号,也是没有问题的)
 
举个栗子:


def csdn():
session=requests.session()
header={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36'}
url='[url]http://msg.csdn.net/'[/url]
    header['Cookie']='uuid_tt_dd=-5697318013068753627_20160111; _ga=GA1.2.795042232.1452766190; _message_m=quvq2wle24wa4awe UserInfo=zMhiNgesgIlEBQ3TOqLCtx4nUI360IIq3ciBzg4EKH%2FW8mSpTANpu5cTlRFLj2Tqh%2FZzQr2rNqDtT1SZz%2Be2%2FpDkGoQxDK3IVUZXvwZ%2FEP1I4UTg6MoZkH7LDO3sjrJJ; UserNick=%E9%87%8D%E5%A4%8D%E7%9A%84%E7%94%9F%E6%B4%BB; AU=0F1; UD=%E8%AE%B0%E5%BD%95%E8%87%AA%E5%AD%A6%E7%9A%84%E5%8E%86%E7%A8%8B+%E5%88%83%E8%8D%; BT=1490707396344; access-token=c2e12bff-5b27-4a91-953b-448ff6f6beac; _csdn_notify_admin_session=VE41a0d3TitrVGY2bGtXY09pZENwR1lHenhUU1NVaWc1b04wL1I3dCtDQVdadWpjMXBzdGRJL0RZR04wYldvZDBhTU96b2oycVVKeVI1UEVyUHFKbG1yNnB2b2pHRWVnWG1uc2JMM2R3YWthakRyTXZNaEpVU1NtUy9zQUJrNjd3R2lpbG5PK0paMnlyc1dyK0lTZUtRPT0tLXlPQUE1QzF5UmhDNjEvSFdtRFlQS2c9PQ%3D%3D--4569c5a32916dcf969a8b7e007c37abeb90be4f3; dc_tos=onj1dg; dc_session_id=1490707393375; Hm_lvt_6bcd52f51e9b3dce32bec4a3997715ac=1490024083,1490024559,1490374375,1490707368; Hm_lpvt_6bcd52f51e9b3dce32bec4a3997715ac=1490707638'
    header['Cache-Control']='max-age=0'
header['Host']='msg.csdn.net'
header['Referer']='http://blog.csdn.net/username'
resp=requests.get(url,headers=header)
print resp.text

 
上面这段代码,只要你改一下cookie和 Refer 的连接,改成你自己的用户名。 你就可以访问你的csdn的消息,也就是别人在你的csdn博客访问的的留言,评论。
 
只是这个cookie只能在某个时间段生效,也就是存活期大概就一个星期左右。


 抓包技术过硬,何须模拟登陆?
 
 
http://30daydo.com/publish/article/155
 

sys.std.write和print的区别

李魔佛 发表了文章 • 0 个评论 • 2659 次浏览 • 2017-03-13 22:00 • 来自相关话题

看别人写的程序,很多地方用sys.std.write,甚少用print。
于是google了下,主要区别在于sys.std.write输出没有换行符,而使用print有换行符
 
引用stackoverflow的例子

print 99


等同于
import sys 
sys.stdout.write(str(99) + '\n')

  查看全部
看别人写的程序,很多地方用sys.std.write,甚少用print。
于是google了下,主要区别在于sys.std.write输出没有换行符,而使用print有换行符
 
引用stackoverflow的例子

print 99


等同于
import sys 
sys.stdout.write(str(99) + '\n')

 

python 爬虫 urllib/requests 中文乱码 终极解决

python爬虫李魔佛 发表了文章 • 0 个评论 • 6738 次浏览 • 2017-03-11 16:17 • 来自相关话题

如果使用的是reqests的包 content=requests.get(url,headers=self.header)
content.encoding='gbk'
print content.text 一般情况 是直接可以content.text 就可以输出网页的内容,不过如果网页的编码不是utf-8的话,需要手动编码
content.encoding='gbk' 
这样content.text就可以正常显示中文。
 
  查看全部
如果使用的是reqests的包
            content=requests.get(url,headers=self.header)
content.encoding='gbk'
print content.text
 一般情况 是直接可以content.text 就可以输出网页的内容,不过如果网页的编码不是utf-8的话,需要手动编码
content.encoding='gbk' 
这样content.text就可以正常显示中文。
 
 

Day6 leetcode Fizz Buzz 字符转换游戏(实在不知道该怎么翻译这个)

李魔佛 发表了文章 • 0 个评论 • 4086 次浏览 • 2017-03-07 11:06 • 来自相关话题

Fizz BuzzWrite a program that outputs the string representation of numbers from 1 to n.

But for multiples of three it should output “Fizz” instead of the number and for the multiples of five output “Buzz”. For numbers which are multiples of both three and five output “FizzBuzz”.

Example:
n = 15,

Return:
[
"1",
"2",
"Fizz",
"4",
"Buzz",
"Fizz",
"7",
"8",
"Fizz",
"Buzz",
"11",
"Fizz",
"13",
"14",
"FizzBuzz"
]
中文解释:
输入一个数字,返回从1到这个数字的所有数字的字符串,如果遇到3的倍数,就替换成Fizz, 遇到5的倍数,就tihu替换成Buzz,同时是3和5的倍数,就tihu替换成FizzBuzz。
 
我的代码:
def fizzBuzz(self, n):
"""
:type n: int
:rtype: List[str]
"""

result=[]
for i in range(1,n+1):
remainder1=i%3
remainder2=i%5
if remainder1 != 0 and remainder2!=0:
result.append(str(i))
elif remainder1==0 and remainder2!=0:
result.append('Fizz')
elif remainder1!=0 and remainder2 == 0:
result.append("Buzz")
else:
result.append("FizzBuzz")

return result 查看全部
Fizz BuzzWrite a program that outputs the string representation of numbers from 1 to n.

But for multiples of three it should output “Fizz” instead of the number and for the multiples of five output “Buzz”. For numbers which are multiples of both three and five output “FizzBuzz”.

Example:
n = 15,

Return:
[
"1",
"2",
"Fizz",
"4",
"Buzz",
"Fizz",
"7",
"8",
"Fizz",
"Buzz",
"11",
"Fizz",
"13",
"14",
"FizzBuzz"
]

中文解释:
输入一个数字,返回从1到这个数字的所有数字的字符串,如果遇到3的倍数,就替换成Fizz, 遇到5的倍数,就tihu替换成Buzz,同时是3和5的倍数,就tihu替换成FizzBuzz。
 
我的代码:
    def fizzBuzz(self, n):
"""
:type n: int
:rtype: List[str]
"""

result=[]
for i in range(1,n+1):
remainder1=i%3
remainder2=i%5
if remainder1 != 0 and remainder2!=0:
result.append(str(i))
elif remainder1==0 and remainder2!=0:
result.append('Fizz')
elif remainder1!=0 and remainder2 == 0:
result.append("Buzz")
else:
result.append("FizzBuzz")

return result

Day5 leetcode Next Greater Element 下一个更大的元素

李魔佛 发表了文章 • 0 个评论 • 4128 次浏览 • 2017-03-03 09:30 • 来自相关话题

You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of nums2. Find all the next greater numbers for nums1's elements in the corresponding places of nums2.

The Next Greater Number of a number x in nums1 is the first greater number to its right in nums2. If it does not exist, output -1 for this number.
 
Example 1:
Input: nums1 = [4,1,2], nums2 = [1,3,4,2].
Output: [-1,3,-1]
Explanation:
For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1.
For number 1 in the first array, the next greater number for it in the second array is 3.
For number 2 in the first array, there is no next greater number for it in the second array, so output -1.Example 2:
Input: nums1 = [2,4], nums2 = [1,2,3,4].
Output: [3,-1]
Explanation:
For number 2 in the first array, the next greater number for it in the second array is 3.
For number 4 in the first array, there is no next greater number for it in the second array, so
Note:


All elements in nums1 and nums2 are unique.
The length of both nums1 and nums2 would not exceed 1000.
 
中文解释下:
有2个数组(列表) num1,和num2,

nums1 = [4,1,2], nums2 = [1,3,4,2].
 
nums1是num2的子集
 
然后在nums1中每个元素,在num2中找到第一个比它大的元素,比如nums1中第一个是4,在nums2中没有比4更大的,所以返回的是-1,nums第二个是1,在nums2中第一个比1大的是3,所以返回的是3,第三个的是2,nums2中第一个比2大的数是3,所以返回的是3
所以上面的结果需要返回:
[-1,3,3] 查看全部
You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of nums2. Find all the next greater numbers for nums1's elements in the corresponding places of nums2.

The Next Greater Number of a number x in nums1 is the first greater number to its right in nums2. If it does not exist, output -1 for this number.
 
Example 1:
Input: nums1 = [4,1,2], nums2 = [1,3,4,2].
Output: [-1,3,-1]
Explanation:
For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1.
For number 1 in the first array, the next greater number for it in the second array is 3.
For number 2 in the first array, there is no next greater number for it in the second array, so output -1.
Example 2:
Input: nums1 = [2,4], nums2 = [1,2,3,4].
Output: [3,-1]
Explanation:
For number 2 in the first array, the next greater number for it in the second array is 3.
For number 4 in the first array, there is no next greater number for it in the second array, so

Note:


All elements in nums1 and nums2 are unique.
The length of both nums1 and nums2 would not exceed 1000.

 
中文解释下:
有2个数组(列表) num1,和num2,

nums1 = [4,1,2], nums2 = [1,3,4,2].
 
nums1是num2的子集
 
然后在nums1中每个元素,在num2中找到第一个比它大的元素,比如nums1中第一个是4,在nums2中没有比4更大的,所以返回的是-1,nums第二个是1,在nums2中第一个比1大的是3,所以返回的是3,第三个的是2,nums2中第一个比2大的数是3,所以返回的是3
所以上面的结果需要返回:
[-1,3,3]

leetcode Day4 Keyboard Row 键盘中的行

李魔佛 发表了文章 • 0 个评论 • 4711 次浏览 • 2017-02-28 22:21 • 来自相关话题

Given a List of words, return the words that can be typed using letters of alphabet on only one row's of American keyboard like the image below.





 
Example 1:
Input: ["Hello", "Alaska", "Dad", "Peace"]
Output: ["Alaska", "Dad"]Note:


You may use one character in the keyboard more than once.
You may assume the input string will only contain letters of alphabet.
 
中文解释:
输入一个字符串列表,如果这个字符串的字母在键盘上的位置为同一行,就输出这个字符串,否则不输出。
 
def findWords( words):
"""
:type words: List[str]
:rtype: List[str]
"""

kb={'q':['q','w','e','r','t','y','u','i','o','p'],
'a':['a','s','d','f','g','h','j','k','l'],
'z':['z','x','c','v','b','n','m']}

rList=[]
qRow= kb['q']
aRow= kb['a']
zRow= kb['z']
for wi in words:
w=wi.lower()
i=0
l=len(w)

if w[0] in qRow:
row=qRow
if w[0] in aRow:
row=aRow
if w[0] in zRow:
row=zRow

#row=kb[w[0]]
for i in range(len(w)):
if w[i] not in row:
break
else:
if i==l-1:
rList.append(wi)
return rList
解释:
首先将字母转换为统一的小写字母,然后根据首字母确定该字符串会属于键盘上的哪一列,因为键盘上只有3列,分别为q,a,z行,如果确定属于q行,接下来将剩下的字符一直在q行内循环,一旦遇到不在q行,就退出这一次的循环,进行下一个字符串的判断。
  查看全部
Given a List of words, return the words that can be typed using letters of alphabet on only one row's of American keyboard like the image below.

keyboard.png

 
Example 1:
Input: ["Hello", "Alaska", "Dad", "Peace"]
Output: ["Alaska", "Dad"]
Note:


You may use one character in the keyboard more than once.
You may assume the input string will only contain letters of alphabet.
 
中文解释:
输入一个字符串列表,如果这个字符串的字母在键盘上的位置为同一行,就输出这个字符串,否则不输出。
 
    def findWords( words):
"""
:type words: List[str]
:rtype: List[str]
"""

kb={'q':['q','w','e','r','t','y','u','i','o','p'],
'a':['a','s','d','f','g','h','j','k','l'],
'z':['z','x','c','v','b','n','m']}

rList=[]
qRow= kb['q']
aRow= kb['a']
zRow= kb['z']
for wi in words:
w=wi.lower()
i=0
l=len(w)

if w[0] in qRow:
row=qRow
if w[0] in aRow:
row=aRow
if w[0] in zRow:
row=zRow

#row=kb[w[0]]
for i in range(len(w)):
if w[i] not in row:
break
else:
if i==l-1:
rList.append(wi)
return rList

解释:
首先将字母转换为统一的小写字母,然后根据首字母确定该字符串会属于键盘上的哪一列,因为键盘上只有3列,分别为q,a,z行,如果确定属于q行,接下来将剩下的字符一直在q行内循环,一旦遇到不在q行,就退出这一次的循环,进行下一个字符串的判断。
 

leetcode Day3 complement number 【补码】

李魔佛 发表了文章 • 0 个评论 • 3313 次浏览 • 2017-02-27 21:47 • 来自相关话题

Given a positive integer, output its complement number. The complement strategy is to flip the bits of its binary representation.

Note:


The given integer is guaranteed to fit within the range of a 32-bit signed integer.
You could assume no leading zero bit in the integer’s binary representation.

Example 1:
 
Input: 5
Output: 2
Explanation: The binary representation of 5 is 101 (no leading zero bits), and its complement is 010. So you need to output 2.
Input: 1
Output: 0
Explanation: The binary representation of 1 is 1 (no leading zero bits), and its complement is 0. So you need to output 0.
解决方法:
class Solution(object):
def findComplement(self, num):
"""
:type num: int
:rtype: int
"""
result=[]
while num!=0:
remainder=num%2
num=num/2
result.append(remainder)
l=len(result)

for i in range(l/2):
temp=result[i]
result[i]=result[l-i-1]
result[l-i-1]=temp
lam=lambda x:abs(x-1)

for i in range(l):
result[i]=lam(result[i])

#print result
sum=0
for i in range(l):
sum=sum+result[l-i-1]*pow(2,i)
return sum
PS: 上面的方法是第一次开始做的最原始的方法,巨傻无比。 完全就是一个没学过计算机原理或者微机原理的人的代码哈。 连一个数的补码这种计算机第一节课的内容都还给老师了。。
 
附上最简便的一个解法:
class Solution(object):
def findComplement(self, num):
i = 1
while i <= num:
i = i << 1
return (i - 1) ^ num
以为其实一个补码就是一个数与另外一个全1的数进行异或处理哈。
鄙视自己!!!
 
  查看全部
Given a positive integer, output its complement number. The complement strategy is to flip the bits of its binary representation.

Note:


The given integer is guaranteed to fit within the range of a 32-bit signed integer.
You could assume no leading zero bit in the integer’s binary representation.

Example 1:
 
Input: 5
Output: 2
Explanation: The binary representation of 5 is 101 (no leading zero bits), and its complement is 010. So you need to output 2.

Input: 1
Output: 0
Explanation: The binary representation of 1 is 1 (no leading zero bits), and its complement is 0. So you need to output 0.

解决方法:
class Solution(object):
def findComplement(self, num):
"""
:type num: int
:rtype: int
"""
result=[]
while num!=0:
remainder=num%2
num=num/2
result.append(remainder)
l=len(result)

for i in range(l/2):
temp=result[i]
result[i]=result[l-i-1]
result[l-i-1]=temp
lam=lambda x:abs(x-1)

for i in range(l):
result[i]=lam(result[i])

#print result
sum=0
for i in range(l):
sum=sum+result[l-i-1]*pow(2,i)
return sum

PS: 上面的方法是第一次开始做的最原始的方法,巨傻无比。 完全就是一个没学过计算机原理或者微机原理的人的代码哈。 连一个数的补码这种计算机第一节课的内容都还给老师了。。
 
附上最简便的一个解法:
class Solution(object):
def findComplement(self, num):
i = 1
while i <= num:
i = i << 1
return (i - 1) ^ num

以为其实一个补码就是一个数与另外一个全1的数进行异或处理哈。
鄙视自己!!!