Селен способ расширить эти таблицы. Есть лучший способ справиться с галстуком, который требуется для загрузки, но просто хотел получить это как можно скорее, поэтому просто пошел с time.sleep
from selenium import webdriver
import time
url = 'http://www.asca.ch/Partners.aspx?lang=it'
driver = webdriver.Chrome()
driver.get(url)
# Click the dropdown, select GE, click Confermo, click Ricerca
driver.find_element_by_xpath('//*[@id="ctl00_MainContent_ddl_cantons_Arrow"]').click()
time.sleep(2)
driver.find_element_by_xpath('//*[@id="ctl00_MainContent_ddl_cantons_DropDown"]/div/ul/li[9]').click()
driver.find_element_by_xpath('//*[@id="MainContent__chkDisclaimer"]').click()
driver.find_element_by_xpath('//*[@id="MainContent_btn_submit"]').click()
time.sleep(5)
#Function to Expand Tables
def expand_tables():
rows = driver.find_elements_by_xpath('//*[@id="MainContent_gw_partners"]/tbody/tr')
for row in rows:
row.click()
# Function to Click Next Page
def click_next_page():
driver.find_element_by_xpath('//*[@id="MainContent_btnNextPackId"]').click()
page = 1
num_of_pages = True
while num_of_pages == True:
print ('Page: %s' %page)
expand_tables()
## Your code to Parse the Tables ##
try:
click_next_page()
page += 1
except:
print ('You are at the end')
time.sleep(2)
# When finished
driver.close()
Выражения в параметрах по умолчанию вычисляются, когда функция определяется, не когда названный it’s.
Пример: рассматривают установку по умолчанию аргумента текущему времени:
>>>import time
>>> def report(when=time.time()):
... print when
...
>>> report()
1210294387.19
>>> time.sleep(5)
>>> report()
1210294387.19
when
аргумент не изменяется. Это оценено при определении функции. Это не изменится, пока приложение не перезапущено.
Стратегия: Вы не споткнетесь за это если Вы параметры по умолчанию к None
и затем делаете что-то полезное, когда Вы будете видеть его:
>>> def report(when=None):
... if when is None:
... when = time.time()
... print when
...
>>> report()
1210294762.29
>>> time.sleep(5)
>>> report()
1210294772.23
Осуществление: для проверки Вы поняли: почему это происходит?
>>> def spam(eggs=[]):
... eggs.append("spam")
... return eggs
...
>>> spam()
['spam']
>>> spam()
['spam', 'spam']
>>> spam()
['spam', 'spam', 'spam']
>>> spam()
['spam', 'spam', 'spam', 'spam']
James Dumay красноречиво напомнил мне из другого глюка Python:
Не все “included Python batteries” замечательны .
определенным примером James’ были библиотеки HTTP: httplib
, urllib
, urllib2
, urlparse
, mimetools
, и ftplib
. Часть функциональности дублирована, и часть функциональности, которую Вы ожидали бы, абсолютно отсутствует, например, обработка перенаправления. Откровенно говоря, это ужасно.
, Если я когда-нибудь должен захватывать что-то через HTTP в эти дни, я использую модуль urlgrabber , разветвленный из Вкусного проекта.
Единственный глюк/удивление, с которым я имел дело, с GIL CPYTHON. Если по любой причине Вы ожидаете, что потоки Python в CPython будут работать, одновременно... хорошо они не, и это вполне прилично документируется толпой Python и даже самим Guido.
А долгое но полное объяснение поточной обработки CPython и некоторые вещи, продолжающиеся под капотом и почему истинный параллелизм с CPython не возможен. http://jessenoller.com/2009/02/01/python-threads-and-the-global-interpreter-lock/
Динамическое связывание делает опечатки в Ваших именах переменной удивительно трудно для нахождения. Легко провести полчаса, исправляя тривиальную ошибку.
РЕДАКТИРОВАНИЕ: пример...
for item in some_list:
... # lots of code
... # more code
for tiem in some_other_list:
process(item) # oops!
Было большое обсуждение скрытых функций языка некоторое время назад: hidden-features-of-python. Где некоторые ловушки были упомянуты (и часть хорошего материала также).
Также Вы могли бы хотеть проверить Бородавки Python .
, Но для меня, целочисленное деление глюк:
>>> 5/2
2
Вы, вероятно, хотели:
>>> 5*1.0/2
2.5
, Если Вы действительно хотите это (подобное C) поведение, необходимо записать:
>>> 5//2
2
, Поскольку это будет работать с плаваниями также (и это будет работать, когда Вы в конечном счете перейдете в Python 3 ):
>>> 5*1.0//2
2.0
GvR объясняет, как целочисленное деление произошло, чтобы работать, как она делает на история Python .
Циклы и лямбды (или любое закрытие, действительно): переменные связываются имя
funcs = []
for x in range(5):
funcs.append(lambda: x)
[f() for f in funcs]
# output:
# 4 4 4 4 4
, работа А вокруг или создает отдельную функцию или передает args по имени:
funcs = []
for x in range(5):
funcs.append(lambda x=x: x)
[f() for f in funcs]
# output:
# 0 1 2 3 4
Необходимо знать, как переменные класса обрабатываются в Python. Рассмотрите следующую иерархию классов:
class AAA(object):
x = 1
class BBB(AAA):
pass
class CCC(AAA):
pass
Теперь, проверьте вывод следующего кода:
>>> print AAA.x, BBB.x, CCC.x
1 1 1
>>> BBB.x = 2
>>> print AAA.x, BBB.x, CCC.x
1 2 1
>>> AAA.x = 3
>>> print AAA.x, BBB.x, CCC.x
3 2 3
Удивленный? Вы не будете то, если Вы будете помнить, что переменные класса внутренне обрабатываются как словари объекта класса. Для операций чтения , если имя переменной не найдено в словаре текущего класса, родительские классы ищутся его. Так, следующий код снова, но с объяснениями:
# AAA: {'x': 1}, BBB: {}, CCC: {}
>>> print AAA.x, BBB.x, CCC.x
1 1 1
>>> BBB.x = 2
# AAA: {'x': 1}, BBB: {'x': 2}, CCC: {}
>>> print AAA.x, BBB.x, CCC.x
1 2 1
>>> AAA.x = 3
# AAA: {'x': 3}, BBB: {'x': 2}, CCC: {}
>>> print AAA.x, BBB.x, CCC.x
3 2 3
То же идет для обработки переменных класса в экземплярах класса (рассматривайте этот пример как продолжение того выше):
>>> a = AAA()
# a: {}, AAA: {'x': 3}
>>> print a.x, AAA.x
3 3
>>> a.x = 4
# a: {'x': 4}, AAA: {'x': 3}
>>> print a.x, AAA.x
4 3
По умолчанию числа с плавающей запятой не печатаются с полной точностью (без repr
):
x = 1.0 / 3
y = 0.333333333333
print x #: 0.333333333333
print y #: 0.333333333333
print x == y #: False
repr
печатает слишком много цифр:
print repr(x) #: 0.33333333333333331
print repr(y) #: 0.33333333333300003
print x == 0.3333333333333333 #: True
Не включая __ init __
.py в ваши пакеты. Этот до сих пор меня иногда достает.
Непреднамеренное смешивание классов старого стиля и нового стиля может вызвать, казалось бы, загадочные ошибки.
Допустим, у вас есть простая иерархия классов, состоящая из суперкласса A и подкласса B. При создании экземпляра B , Сначала должен быть вызван конструктор A. Приведенный ниже код делает это правильно:
class A(object):
def __init__(self):
self.a = 1
class B(A):
def __init__(self):
super(B, self).__init__()
self.b = 1
b = B()
Но если вы забыли сделать A классом нового стиля и определите его следующим образом:
class A:
def __init__(self):
self.a = 1
вы получите эту трассировку:
Traceback (most recent call last):
File "AB.py", line 11, in <module>
b = B()
File "AB.py", line 7, in __init__
super(B, self).__init__()
TypeError: super() argument 1 must be type, not classobj
Два других вопроса, связанных с этой проблемой: 489269 и 770134
Вы не можете использовать locals () ['x'] = что угодно для изменения значений локальных переменных, как вы могли ожидать.
This works:
>>> x = 1
>>> x
1
>>> locals()['x'] = 2
>>> x
2
BUT:
>>> def test():
... x = 1
... print x
... locals()['x'] = 2
... print x # *** prints 1, not 2 ***
...
>>> test()
1
1
Это фактически сожгло меня в ответе здесь, на SO, так как я тестировал его вне функции и получил желаемое изменение. Впоследствии я обнаружил, что он упоминается и противопоставляется случаю globals () в «Dive Into Python». См. Пример 8.12. (Хотя он не отмечает, что изменение с помощью locals () будет работать на верхнем уровне, как я показал выше.)
] = что угодно, чтобы изменить значения локальных переменных, как и следовало ожидать.This works:
>>> x = 1
>>> x
1
>>> locals()['x'] = 2
>>> x
2
BUT:
>>> def test():
... x = 1
... print x
... locals()['x'] = 2
... print x # *** prints 1, not 2 ***
...
>>> test()
1
1
Это фактически сожгло меня в ответе здесь, на SO, поскольку я тестировал его вне функции и получил желаемое изменение. Впоследствии я обнаружил, что он упоминается и противопоставляется случаю globals () в «Dive Into Python». См. Пример 8.12. (Хотя он не отмечает, что изменение с помощью locals () будет работать на верхнем уровне, как я показал выше.)
] = что угодно, чтобы изменить значения локальных переменных, как и следовало ожидать.This works:
>>> x = 1
>>> x
1
>>> locals()['x'] = 2
>>> x
2
BUT:
>>> def test():
... x = 1
... print x
... locals()['x'] = 2
... print x # *** prints 1, not 2 ***
...
>>> test()
1
1
Это на самом деле сожгло меня в ответе здесь, на SO, так как я тестировал его вне функции и получил желаемое изменение. Впоследствии я обнаружил, что он упоминается и противопоставляется случаю globals () в «Dive Into Python». См. Пример 8.12. (Хотя он не отмечает, что изменение с помощью locals () будет работать на верхнем уровне, как я показал выше.)