urllib2.urlopen返回空内容
我一直在用一段代码来读取IMDb的页面,直到几天前它还正常工作。但前几天我想运行它时,发现urllib2.urlopen返回的响应是空的。它没有报错——它声称返回的是正确的。只是没有数据。
当我在浏览器里打开该页面时,显示是正常的。用浏览器的开发者工具查看,起初它显示该请求返回为空,但等一会儿,页面的HTML源码就按预期出现。
如果有帮助的话,下面是我代码相关的部分:
import urllib2
def openConnection(URL):
try:
req = urllib2.Request(URL, headers={'User-Agent' : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"})
context = ssl._create_unverified_context()
con = urllib2.urlopen( req, context=context )
for line in con:
print line
return con
except:
print "Connection failed. Retrying."
def readIMDB(movie):
data = openConnection("https://www.imdb.com/title/" + movie + "/fullcredits")
readIMDB("tt0084726")
顺便说一句,那个for循环和打印语句只是为了测试而添加的。把任意其他URL传给openConnection时,它会按行输出页面内容,符合预期。不过对于这个URL,这个for循环却执行了零次。
我的问题是,为什么这个特定页面在浏览器里显示得很好,但程序却没有返回任何数据?是否有我可以修改的地方来获得这些数据?
解决方案
有些服务器可能会使用检测脚本/机器人访问的复杂系统,或许他们已经检测到你在使用脚本,于是对你进行了屏蔽。
I get the same problem when I use urlib2 (in Python 2) and requests (in Python 3) or even with programs curl or wget
如果我添加头信息(在浏览器中打开你的页面时Firefox发送的头信息)
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
那么Python会显示HTML,但只有信息
<h1>JavaScript is disabled</h1>
In order to continue, we need to verify that you're not a robot.
This requires JavaScript. Enable JavaScript and then reload the
page.that it needs JavaScript to verify browser.
但 urllib2、requests 不能运行JavaScript。
因此可能需要 Selenium 来控制能够运行JavaScript的网页浏览器。
我用Selenium也做了测试,如果你不等待,它也会显示关于JavaScript的提示信息。
但在等待之后就会得到预期的HTML。
from selenium import webdriver
import time
number = "tt0084726"
url = "https://www.imdb.com/title/{}/fullcredits".format(number)
with webdriver.Firefox() as driver:
driver.get(url)
#print(driver.page_source) # <-- only information about JavaScript
time.sleep(3) # <-- time to run JavaScript
print(driver.page_source) # <-- expected HTML
或者你得等到页面上出现在预期页面中存在的某个元素
from selenium import webdriver
from selenium.webdriver.common.by import By
number = "tt0084726"
url = "https://www.imdb.com/title/{}/fullcredits".format(number)
with webdriver.Firefox() as driver:
driver.get(url)
driver.implicitly_wait(3)
driver.find_element(By.CSS_SELECTOR, "main")
print(driver.page_source)
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。