python爬取12306车票信息返回结果错误?


import requests
from urllib.parse import urlencode
def get_ticket():
    base_url = 'https://kyfw.12306.cn/otn/leftTicket/query?'
    data = {
        'leftTicketDTO.train_date': '2023-09-13',
        'leftTicketDTO.from_station': 'ZBK',
        'leftTicketDTO.to_station': 'SHH',
        'purpose_codes': 'ADULT'
    }
    url = base_url + urlencode(data)
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.76',
        'Cookie': '_uab_collina=169268293571358642590996; JSESSIONID=74620F6C03FD6CD075C6630932DFC156; guidesStatus=off; _jc_save_wfdc_flag=dc; highContrastMode=defaltMode; cursorStatus=off; route=495c805987d0f5c8c84b14f60212447d; BIGipServerotn=1911030026.50210.0000; _jc_save_fromStation=%u6DC4%u535A%2CZBK; _jc_save_toStation=%u4E0A%u6D77%2CSHH; _jc_save_fromDate=2023-09-12; _jc_save_toDate=2023-09-12'
    }
    response = requests.get(url, headers=headers)
    response.encoding = 'utf-8'
    print(response.text)
get_ticket()

爬取12306的车票信息,之前运行程序结果没有问题,返回的是一个json数据,

img

但是今天运行了一下返回的结果却是一个html网页数据,上网找了一下原因说是cookie可是程序里明明加上cookie了啊,而且换了几个cookie运行结果仍然是这个,期间换了一次宽带,难道是这个原因?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>铁路客户服务中心</title>
<link href="/mormhweb/images/global.css" rel="stylesheet" type="text/css">
<link href="/mormhweb/images/err.css" rel="stylesheet" type="text/css"/>
<style type="text/css"> 
<!--
html,body{background:#fff;}


-->
</style>


</head>

<body>
<div class="err_text">
                         <ul id="error" >
                         <li id="err_top">
                         
                         </li>
                                                  <li id="err_bot">  网络可能存在问题,请您重试一下!
                                                  
                                                  <div class="time">                         <SCRIPT language="javascript">
<!--
function initArray() {
    for (i = 0; i < initArray.arguments.length; i++)
        this[i] = initArray.arguments[i];
}
var isnMonths = new initArray("1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月");
var isnDays = new initArray("星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日");
today = new Date();
hrs = today.getHours();
min = today.getMinutes();
sec = today.getSeconds();
clckh = "" + ((hrs > 12) ? hrs - 12 : hrs);
clckm = ((min < 10) ? "0" : "") + min;
clcks = ((sec < 10) ? "0" : "") + sec;
clck = (hrs >= 12) ? "下午" : "上午";
var stnr = "";
var ns = "0123456789";
var a = "";

function getFullYear(d) {
    yr = d.getYear();
    if (yr < 1000)
        yr += 1900;
    return yr;
}

document.write(getFullYear(today) + "年" + isnMonths[today.getMonth()] + today.getDate() + "日" + " " + clckh + ":" + clckm + ":" + clcks + " " +  isnDays[today.getDay()]);

//-->
</SCRIPT></div>
                            
                         
                         </li>

                         </ul>

</div>
</body>
</html>

import requests

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
}
res = requests.get('https://kyfw.12306.cn/index/otn/index12306/getServiceList', headers=headers)
cookies = {
    'JSESSIONID': res.cookies.get_dict()  ['JSESSIONID'],
}
params = {
    'leftTicketDTO.train_date': '2023-09-13',
    'leftTicketDTO.from_station': 'LHM',
    'leftTicketDTO.to_station': 'DKM',
    'purpose_codes': 'ADULT',
}

response = requests.get('https://kyfw.12306.cn/otn/leftTicket/queryZ', params=params, cookies=cookies, headers=headers)

引用 皆我百晓生 小程序回复内容作答:
从你提供的代码和错误信息来看,问题可能出在以下几个方面:

  1. 网页结构变化:12306网站可能进行了更新,导致之前的爬虫代码无法正确解析返回的数据。你可以尝试使用浏览器开发者工具查看请求的真正结果,确认返回的数据结构是否仍然是JSON格式。

  2. Cookie问题:尽管你在代码中添加了Cookie,但是cookie的有效性可能受到其他因素的影响,如IP地址变动、账号状态等。你可以尝试更新Cookie,或者使用其他技巧来绕过可能的反爬机制。

  3. IP封禁:如果你频繁地发送请求,或者使用了一些被网站认为是恶意的行为,你的IP地址可能被封禁,导致返回的结果是错误的。你可以尝试使用代理IP来解决这个问题。

综上所述,你可以分别尝试调试代码、更新Cookie、使用代理IP等方法来解决返回结果错误的问题。

12306 属于完全动态页面,当你进行外部资源爬去的时候,他会出发拒绝访问。也就是说你爬去不到。

【以下回答由 GPT 生成】

如何解决爬取12306车票信息返回错误的问题?

问题中提到,爬取12306车票信息的代码之前能够正常运行,返回JSON数据,但是最近返回的是一个HTML网页数据。已经尝试添加不同的Cookie,但问题依然存在。

可能的原因是:

  1. 服务器返回了验证码页面,要求用户验证。
  2. Cookie可能不正确或已过期,需要更新Cookie。
  3. IP地址被封禁,需要更换IP地址。

针对以上可能的原因,我们可以尝试以下解决方案:

方案一:处理验证码

如果服务器返回了验证码页面,我们需要对验证码进行处理,以继续爬取数据。

  1. 首先,根据返回的HTML网页,提取出验证码图片的URL。
  2. 使用requests库下载验证码图片,并保存到本地。
  3. 调用Tesseract OCR或其他OCR库来自动识别验证码。
  4. 将识别结果填写到请求参数中的验证码字段。
  5. 继续发送请求,获取返回的数据。
import requests
import pytesseract
from PIL import Image

# 下载验证码图片并保存到本地
def download_captcha(captcha_url):
    response = requests.get(captcha_url)
    with open('captcha.png', 'wb') as f:
        f.write(response.content)

# 识别验证码图片
def recognize_captcha():
    image = Image.open('captcha.png')
    captcha = pytesseract.image_to_string(image)
    return captcha

# 添加识别后的验证码到请求参数
def add_captcha_to_params(params, captcha):
    params['captcha'] = captcha

# 发送请求获取数据
def get_ticket():
    # ...
    captcha_url = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand'
    download_captcha(captcha_url)
    captcha = recognize_captcha()
    add_captcha_to_params(data, captcha)
    # ...

如果Cookie不正确或已过期,我们可以尝试更新Cookie。

  1. 打开浏览器,登录12306官网,获取最新的Cookie信息。
  2. 将最新的Cookie替换到代码中的Cookie字段。
headers = {
    'User-Agent': '...',
    'Cookie': '最新的Cookie信息'
}

方案三:更换IP地址

如果IP地址被封禁,我们可以尝试更换IP地址。

  1. 使用代理服务器发送请求,以隐藏真实IP地址。
  2. 可以使用第三方库,如requests或treq,在发送请求时设置代理服务器。
proxies = {
    'http': 'http://代理服务器IP地址:端口号',
    'https': 'https://代理服务器IP地址:端口号'
}

response = requests.get(url, headers=headers, proxies=proxies)

请注意,以上的解决方案是一种可能的方法。由于12306官网可能会对爬虫进行限制和反爬虫策略,所以无法保证以上方案一定能解决问题。您仍然需要在合理合法的范围内进行爬取,请尊重网站的使用规则,并遵守相关法律法规。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^