环境:
python -ver3.6.3
pip -ver9.0.1
Flask -ver0.12.2 //因为程序是基于php运行,调用的python脚本,并且两者并不部署在同一个服务器上,因此选择了Flask框架。
request -ver2.18.4
selenium -ver3.11.0
lxml -ver4.2.1
beautifulsoup4 -ver4.6.0
其它的内容等整个功能全部写完之后再补充
遇到的问题:
20180329:【某天】的规格样式暂时发现4种,由于没有爬虫经验,所以在事先了解网站页面构成方面并不是很上心,于是就遇到了问题。
Q:因为之前都是table布局行列规格的样式,现在突然发现还有select option选择规格的样式,那么在不确定select数量的前提下,该如何进行规格的笛卡尔积组合?
A:暂时只知道一种方式,python中可以from itertools import product,此函数可以为list进行笛卡尔积组合。但是因为不确定select的数量,也就不确定list的数量,product()中传递的list数量就无法确定。这里也是以前从没有遇到过类似的问题,好在有同事提醒,可以用*args的方式来解决参数问题。
举例:#考虑用dict将所有页面上抓取到的相关select以list形式存入
from itertools import product
dict = {'1': ['a', 'b'], '2': ['c', 'd','c1', 'd1','c2', 'd2','c3', 'd3'], '3':['e', 'f','e1', 'f1','e2', 'f2','e3', 'f3','e4', 'f4','e5', 'f6'], '4': ['g']}
list = dict.values()
for v in product(*list)
print(v)
#如此就可以将所有的排列组合全部获取到,并且list是动态数量,与此类似的是js中的三点操作符(...args)
Q:因为要获取规格,但是【某天】很多原本应该放规格的option中放了提示,这很让人头疼,完全找不出任何区别,索性就决定建个字典去进行过滤,但是在过滤的途中遇到了一个问题,IndexError: list index out of range,很明显的越界问题。
A:因为目的是要对获取到的页面option进行过滤,而数据是存入到了list中,字典也是用list的形式建立,两个list起初是用for循环,然后存在于字典中的元素将会被删除,直接导致了问题的发生。因为在最初规定了循环次数,而当list中的元素被删除之后,list的长度减少,已经不符合最初规定的循环次数的长度,所以才发生了越界问题。解决的办法是用while循环取代for循环,在最初进行长度判断,并且在删除元素之后将下标减1,以此来保证所有元素都会被遍历到。
后续补充:发现了一种更有趣的写法,而且更简洁不容易混乱,用filter和lambda表达式组合实现需求。
举例:
test_list = [[1], [], [], [2]]
#第一个for循环会直接报错 IndexError: list index out of range
for num in range(0, len(test_list)):
if len(test_list[num]) == 0:
del test_list[num]
print(test_list)
#第二个可以顺利运行并输出结果[[1], [2]]
num = 0
while num < len(test_list):
if len(test_list[num]) == 0:
del test_list[num]; num -= 1
num += 1
del num
print(test_list)
#因为在python3中,filter的返回值不再是list而是filter类和地址,所以需要转换成list
a = [1, 2, 0, 3, 4, 0, 5, 0, 6]
a = list(filter(lambda x: x > 0, a))
print(a)
Q:爬取一个分类页面的时候出现了乱码情况
A:经过一系列的查询和修改,最终解决,是request库编码出现了问题,将request.text改成request.content问题解决。
Q:有时候会出现多维list或者tuple嵌套的情况,然而如(('a')) or [[],['b']]这两种,我希望将其变成一维的而不是多维的。
A:导入_flatten,可以将多维的list或者tuple转成一维的。不过返回值是tuple类型的,如有需求需要另外转换。
举例:
from tkinter import _flatten
a = (('a',),)
b = [[], [1]]
print('a =>', a)
print('b =>', b)
print('f(a) =>', _flatten(a))
print('f(b) tuple =>', _flatten(b))
print('f(b) list =>', list(_flatten(b)))
# a => (('a',),)
# b => [[], [1]]
# f(a) => ('a',)
# f(b) tuple => (1,)
# f(b) list => [1]
因为存储处理和爬抓是在不同服务器上的,因此使用了flask,本地使用的SSH管理的服务器,每次关闭终端都会导致服务中断,或者当时间过久也会自动断开连接,为了解决这个问题,选择了screen去管理。
简单介绍:
Screen是一款由GNU计划开发的用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换。GNU Screen可以看作是窗口管理器的命令行界面版本。它提供了统一的管理多个会话的界面和相应的功能。
下载:yum -y install screen
创建一个新的会话:screen -R <name>
进入一个会话:screen -r <name>
查看正在运行的会话:screen -ls
删除一个会话:screen -X -S <name> quit
使用的时候曾遇到过一个问题,就是会话的状态是Attached的时候,无法访问会话。
解决方法:screen -D -r <session ID>