С помощью lxml.html
вы можете позвонить parse
напрямую с помощью URL, чтобы вам не пришлось звонить urllib
самостоятельно. Кроме того, вместо использования find
или findall
вы захотите вызвать xpath
, чтобы вы получили полную выразительность xpath ; если вы попытались вызвать то же выражение ниже, используя find
, он вернет ошибку invalid predicate
.
#!/usr/bin/env python
import lxml.html
url = "http://www.yellowpages.com.au/search/listings?clue=architects&locationClue=New+South+Wales&x=45&y=12"
tree = lxml.html.parse(url)
listings = tree.xpath("//span[contains(@id,'listing-name-')]/text()")
print listings
выведет это, сохранив порядок:
['Cape Cod Australia Pty Ltd',
'BHI',
'Fibrent Pty Ltd Building & Engineering Assessments',
...
'Archicentre']
Чтобы ответить на вопрос в ваших комментариях к моему ответу, вам нужно найти <div class="listingInfoContainer">...</div>
, который содержит всю необходимую вам информацию. (имя, адрес и т. д.). Затем вы можете просмотреть список элементов div, соответствующих этим критериям, и использовать выражения xpath для извлечения остальной информации. Обратите внимание, что в этом случае я использую container.xpath('.//span')
, который будет искать с текущего узла (контейнера div), в противном случае, если вы пропустите .
и просто наберете //span
, он начнет поиск с вершины дерева и вы получите список всех совпадающих элементов, а это не то, что вам нужно после выбора узла контейнера.
#!/usr/bin/env python
import lxml.html
url = "http://www.yellowpages.com.au/search/listings?clue=architects&locationClue=New+South+Wales&x=45&y=12"
tree = lxml.html.parse(url)
container = tree.xpath("//div[@class='listingInfoContainer']")
listings = []
for c in container:
data = {}
data['name'] = c.xpath('.//span[contains(@id,"listing")]/text()')
data['address'] = c.xpath('.//span[@class="address"]/text()')
listings.append(data)
print listings
который выводит:
[{'name': ['Cape Cod Australia Pty Ltd'],
'address': ['4th Floor 410 Church St, North Parramatta NSW 2151']},
{'name': ['BHI'],
'address': ['Suite 5, 65 Doody St, Alexandria NSW 2015']},
{'name': ['Fibrent Pty Ltd Building & Engineering Assessments'],
'address': ["Suite 3B, Level 1, 72 O'Riordan St, Alexandria NSW 2015"]},
...
{'name': ['Archicentre'],
'address': ['\n Level 3, 60 Collins St\n ',
'\n Melbourne VIC 3000\n ']}]
- это список (опять же, сохраняя порядок, который вы хотели) словарей с ключами name
и address
, каждый из которых содержит список. Этот окончательный список возвращается text()
, который сохраняет символы новой строки \n
в оригинальном HTML и переводит такие вещи, как <br>
, в новый элемент списка. Примером того, почему это так, является элемент списка Archicentre, в котором исходное представление HTML имеет вид:
<span class="address">
Level 3, 60 Collins St
<br/>
Melbourne VIC 3000
</span>