我正在制作一个爬虫。 用户可以指定正则表达式字符串来下载数据。
当用户输入表格为:
时http://xxx/abc[x-z]/image(9|10|11).png
我想下载这些。
http://xxx/abcx/image9.png
http://xxx/abcy/image9.png
http://xxx/abcz/image9.png
http://xxx/abcx/image10.png
http://xxx/abcy/image10.png
http://xxx/abcz/image10.png
http://xxx/abcx/image11.png
http://xxx/abcy/image11.png
http://xxx/abcz/image11.png
我可以从上面的正则表达式字符串创建以下列表吗?或者,我可以在for-in块中使用每个字符串吗?
答案 0 :(得分:6)
如果您想要将用户的正则表达式作为输入并生成字符串列表,您可以使用库sre_yield:
然而,要非常清楚,尝试解析每个可能的正则表达式字符串可能会很快失控。您需要确保您的用户了解通配符和开放式或重复组对可能匹配的字符串数量的影响。
例如,您的正则表达式字符串:http://xxx/abc[x-z]/image(9|10|11).png
不会转义.
,这是任何字符的通配符,因此会生成许多意外的字符串。相反,我们需要转义它,如下例所示:
>>> import sre_yield
>>> links = []
>>> for each in sre_yield.AllStrings(r'http://xxx/abc[x-z]/image(9|10|11)\.png'):
links.append(each)
或更简单地links = list(sre_yield.AllStrings(r'http://xxx/abc[x-z]/image(9|10|11)\.png'))
结果是:
>>> links
['http://xxx/abcx/image9.png', 'http://xxx/abcy/image9.png',
'http://xxx/abcz/image9.png', 'http://xxx/abcx/image10.png',
'http://xxx/abcy/image10.png', 'http://xxx/abcz/image10.png',
'http://xxx/abcx/image11.png', 'http://xxx/abcy/image11.png',
'http://xxx/abcz/image11.png']
答案 1 :(得分:1)
您可以使用product()
内置版中的itertools
:
from itertools import product
for x, y in product(['x', 'y', 'z'], range(9, 12)):
print 'http://xxx/abc{}/image{}'.format(x, y)
要构建列表,您可以使用理解:
links = ['http://xxx/abc{}/image{}'.format(x, y) for x, y in product(['x', 'y', 'z'], range(9, 12))]
答案 2 :(得分:0)
简单的尝试可能是以前的答案的替代
lst = ['http://xxx/abc%s/image%s.png'%(x,y) for x, y in [(j,i) for i in (9,10,11) for j in ('x', 'y', 'z')]]
省略range
和format
功能,以便更快地发挥作用。
分析 - 我比较了我的方式和Jkdc
我跑了 100000次,但意味着 itertools 方法在执行时间方面更快 -
from itertools import product
import time
from matplotlib import pyplot as plt
import numpy as np
prodct = []
native = []
def test():
start = time.clock()
lst = ['http://xxx/abc{}/image{}'.format(x, y) for x, y in product(('x', 'y', 'z'), range(9, 11))]
end = time.clock()
print '{0:.50f}'.format(end-start)
prodct.append('{0:.50f}'.format(end-start))
start1 = time.clock()
lst = ['http://xxx/abc%s/image%s'%(x,y) for x, y in [(j,i) for i in (9,10,11) for j in ('x', 'y', 'z')]]
end1 = time.clock()
print '{0:.50f}'.format(end1-start1)
native.append('{0:.50f}'.format(end1-start1))
for i in range(1,100000):
test()
y = np.dot(np.array(native).astype(np.float),100000)
x= np.dot(np.array(prodct).astype(np.float),100000)
print np.mean(y)
print np.mean(x)
并获得native
(无模块)和itertools-product
的结果,如下所示
2.1831179834
的
for itertools-product 1.60410432562