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爬虫中常见问题与解决方案

9 回复

手动点一下看看真正的请求是什么去抓就行


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)

总结建议:爬虫的关键是模拟真人操作,别太贪心一次抓太多。

0.应该是的
1.不需要再 get
2.如果能 get 何必要虚拟点击,囧~

不知为何,我的部分代码没有正确显示出来,我重新贴一下我的完整问题吧。

在爬取某网站时,要根据页面上的选择页控件接着爬取下一个页面,但是控件中下一页的网址并没有直接给出来,而是形如这样的源码:<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 了吧?

1.那部分内容可能是 js 渲染的,你得等待一会----可以用个循环( time.sleep(1)一直检测那个元素出来没,出来了再做后面解析
2.nextpageButton 我没那么写过,我最多直接用 driver.find_element_by_xpath,你那么套我不清楚找的对不对
3.及时模拟点击了,后面有些内容可能也要睡一会才出现的(重新获取 driver.page_source )
4.极力请使用 ChromeDriver,可以直接看到界面----每句语句的效果。phantomjs 已经没人维护了~

用 phantomJS 是为了起到无界面浏览器的效果,不知 ChromeDriver 可以起到同样效果么?

nextpageButton = driver.find_element_by_xpath(‘a/@onclick’)
nextpageButton.click()
如果是 ajax 加载,则 time.sleep(10)

phantomJS 已经被放弃了,chrome 60 以上的版本支持 headless 模式,可以在调试时使用界面,生产时使用 headless

import pdb
pdb.set_trace()

回到顶部