一、动态与静态网页的区别
在了解Python动态爬虫之前,我们需要先理解动态与静态网页的区别。简单来说,静态网页是固定的HTML代码,展示给用户的页面内容是由服务器直接返回给浏览器的,而动态网页在客户端交互的过程中才生成HTML代码。这种动态生成HTML代码的网页我们也称之为AJAX网页,它们通常使用JavaScript完成。
静态网页的抓取比较简单,只需要抓取整个HTML文件就好。但是对于动态网页,由于它们是在客户端生成HTML代码,所以只需要请求网页源代码时无法获取完整数据,需要使用Selenium或者PhantomJS之类的工具进行模拟点击和JavaScript解析。
二、使用Selenium进行动态网页抓取
Selenium是一种自动化测试工具,可以用于模拟用户在浏览器中的操作。我们可以通过Selenium来操作浏览器模拟点击、填写表单等操作,从而得到完整的网页数据。
首先,我们需要安装Selenium库和相应的浏览器驱动,比如Chrome浏览器驱动:
pip install selenium
然后,我们需要启动浏览器并打开页面:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://example.com')
最后,我们可以通过Selenium模拟用户的操作,比如点击按钮或者滚动页面。例如,下面的例子中,我们模拟点击了一个按钮,并等待页面加载完毕:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver.find_element(By.ID, 'button').click()
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'result')))
三、使用BeautifulSoup解析网页内容
在获取到网页源代码之后,我们需要使用解析器来提取需要的数据。这里我们可以使用Python中最流行的解析库之一:BeautifulSoup。
我们可以使用BeautifulSoup来提取HTML标签和属性、内容等信息。例如,下面的例子中,我们通过BeautifulSoup提取了一个列表中所有链接的URL:
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
links = soup.select('ul > li > a')
for link in links:
print(link['href'])
四、一个完整的动态网页爬虫实例
下面是一个完整的动态网页爬虫实例,它使用Selenium模拟用户登录GitHub并抓取用户仓库的名称和URL。需要注意的是,由于GitHub网站的反爬虫机制,我们还需要设置Selenium的代理IP。完整代码如下:
from selenium import webdriver
from bs4 import BeautifulSoup
proxy = 'http://127.0.0.1:8080'
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--proxy-server=%s' % proxy)
driver = webdriver.Chrome(options=chrome_options)
driver.get('https://github.com/login')
# Fill in username and password
driver.find_element_by_id('login_field').send_keys('your_username')
driver.find_element_by_id('password').send_keys('your_password')
driver.find_element_by_name('commit').click()
# Wait for page to load
driver.implicitly_wait(10)
# Navigate to user's repositories page
driver.get('https://github.com/your_username?tab=repositories')
# Get page content
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
# Extract repository names and URLs
repositories = soup.find_all('a', itemprop='name codeRepository')
names = [r.text.strip() for r in repositories]
urls = [r['href'] for r in repositories]
# Print results
for name, url in zip(names, urls):
print(name + ': ' + url)
# Quit browser
driver.quit()