Python爬虫中常见问题与解决方案
在爬取某网站时,要根据页面上的选择页控件接着爬取下一个页面,但是控件中下一页的网址并没有直接给出来,而是形如这样的源码:3 其中的 queryListByPage 应该是点击“ 3 ”这个页码的方框时会触发的函数。我想用 selenium.webdriver 和 PhantomJS 来模拟点击页码并进入下一页面的动作,我写了如下的语句:
nextpageButton = driver.find_element_by_name(response.xpath('a/@click').extract())
nextpageButton.click()
我面临的问题如下:
1、上面的语句是否可以实现模拟点击下一页页码按钮的效果
2、如果上面语句可以模拟点击下一页,那么执行完毕后,是否还要有加载下一页面的动作?也就是说还要执行诸如 driver.get(下一页网址) 的语句?并且下一页面的网址要如何获取,有什么函数可以直接返回这个网址么?
恳请指点,感谢!
Python爬虫中常见问题与解决方案
手动点一下看看真正的请求是什么去抓就行
Python爬虫常见问题与解决方案
爬虫搞不定?多半是这几个地方卡住了。我整理了几个最常见的问题和对应的代码解决方案,你对照看看。
1. 请求被网站屏蔽(反爬虫) 这是最头疼的问题。网站一看你请求太频繁或者没有正常浏览器特征,就直接给你封了。
import requests
import time
from fake_useragent import UserAgent
ua = UserAgent()
headers = {
'User-Agent': ua.random,
'Accept-Language': 'zh-CN,zh;q=0.9',
'Referer': 'https://www.example.com/'
}
# 关键:加延迟,别猛请求
for page in range(1, 6):
response = requests.get(f'https://example.com/page/{page}', headers=headers)
# 处理响应数据...
time.sleep(2) # 每请求一次停2秒
2. 动态加载内容抓不到 很多网站用JavaScript动态加载数据,你直接requests.get()拿到的是空页面。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get('https://example.com')
# 等元素加载出来
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "content"))
)
# 现在可以获取动态内容了
dynamic_content = driver.page_source
finally:
driver.quit()
3. 需要登录才能访问 有些页面要先登录,你得带上cookie或者session。
import requests
session = requests.Session()
# 先登录
login_data = {
'username': 'your_username',
'password': 'your_password'
}
session.post('https://example.com/login', data=login_data)
# 用同一个session访问需要登录的页面
response = session.get('https://example.com/protected-page')
4. 数据解析出问题 HTML结构复杂,用错方法就解析不到数据。
from bs4 import BeautifulSoup
import re
html_doc = """<html>你的HTML内容</html>"""
soup = BeautifulSoup(html_doc, 'html.parser')
# 多种查找方式,总有一种能抓到
# 按class找
items = soup.find_all('div', class_='item')
# 按属性找
links = soup.find_all('a', href=True)
# 用CSS选择器
titles = soup.select('h1.title')
# 正则表达式匹配
pattern = re.compile(r'data-id="(\d+)"')
matches = pattern.findall(html_doc)
5. 编码问题乱码 特别是中文网站,编码不对就一堆乱码。
response = requests.get('https://example.com')
# 先看网站用什么编码
print(response.encoding) # 可能是ISO-8859-1
# 手动指定正确编码
response.encoding = 'utf-8' # 或者'gbk'、'gb2312'
content = response.text
6. 被封IP怎么办 请求太猛会被封IP,这时候要用代理。
proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
}
response = requests.get('https://example.com', proxies=proxies, timeout=10)
总结建议:爬虫的关键是模拟真人操作,别太贪心一次抓太多。
不知为何,我的部分代码没有正确显示出来,我重新贴一下我的完整问题吧。
在爬取某网站时,要根据页面上的选择页控件接着爬取下一个页面,但是控件中下一页的网址并没有直接给出来,而是形如这样的源码:<a onclick=“queryListByPage(‘3’)”>3</a>
其中的 queryListByPage 应该是点击“ 3 ”这个页码的方框时会触发的函数。我想用 selenium.webdriver 和 PhantomJS 来模拟点击页码并进入下一页面的动作,我写了如下的语句:
nextpageButton = driver.find_element_by_name(response.xpath(‘a/onclick’).extract())
nextpageButton.click()
我面临的问题如下:
1、上面的语句是否可以实现模拟点击下一页页码按钮的效果
2、如果上面语句可以模拟点击下一页,那么执行完毕后,是否还要有加载下一页面的动作?也就是说还要执行诸如 driver.get(下一页网址) 的语句?并且下一页面的网址要如何获取,有什么函数可以直接返回这个网址么?
假如 nextpageButton.click() 这个语句就等同于 driver.get(下一页网址) 这个语句的效果,那么请问,包含下一个页面内容的对象是什么? 应该不是 response 了吧?
nextpageButton = driver.find_element_by_xpath(‘a/@onclick’)
nextpageButton.click()
如果是 ajax 加载,则 time.sleep(10)
phantomJS 已经被放弃了,chrome 60 以上的版本支持 headless 模式,可以在调试时使用界面,生产时使用 headless
import pdb
pdb.set_trace()


