Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python module BeautifulSoup extracting anchors href

i am using BeautifulSoup module to select all href from html by this way:

def extract_links(html):
  soup = BeautifulSoup(html)
  anchors = soup.findAll('a')
  print anchors
  links = []
  for a in anchors:
    links.append(a['href'])
  return links

but sometime it failed by this error message:

Traceback (most recent call last):
File "C:\py\main.py", line 33, in <module>
urls = extract_links(page)
File "C:\py\main.py", line 11, in extract_links
links.append(a['href'])
File "C:\py\BeautifulSoup.py", line 601, in __getitem__
return self._getAttrMap()[key]
KeyError: 'href'
like image 407
Michal Avatar asked Jan 29 '12 23:01

Michal


3 Answers

Not all anchor tags will have an href attribute. You should check that the anchor has an href before you try to access that attribute.

if a.has_key('href')
  links.append(a['href'])

After checking some comments here, I think this is the most pythonic way of handling this case.

like image 99
tjarratt Avatar answered Oct 19 '22 16:10

tjarratt


Try this.

links = [a['href'] for a in anchors if a.has_key('href')]

Or, if you'd rather mutate an existing list

links = []
#...
links.extend(a['href'] for a in anchors if a.has_key('href'))
like image 22
Matt Luongo Avatar answered Oct 19 '22 15:10

Matt Luongo


soup.findAll() returns a list of "tags", that contain dictionaries of attributes. So you need to extract its attributes and work on them.

Taking your example and modifying, this is the code that works:

def extract_links(html):
  soup = BeautifulSoup(html)
  anchors = soup.findAll('a')
  print anchors
  links = []
  for a in anchors:
    if a.attrs.has_key('href'):
      links.append(a['href'])
return links
like image 2
Aditya Avatar answered Oct 19 '22 15:10

Aditya