I am trying to find a string in the headers of response after login in Wordpress script, so I tried with this find method:
import urllib, urllib2, os, sys, requests , re
....
....
req = urllib2.Request(url, urllib.urlencode(dict(data)), dict(headers))
response = urllib2.urlopen(req)
res = dict(response.headers)
res1 = 'wp-admin'
if res.find(res1) >= 0:
print 'wp-admin exist in dict(response.headers)'
and i get this error :
Traceback (most recent call last):
File "C:\Python27\wp2\wp12.py", line 29, in <module>
if res.find(res1) >= 0:
AttributeError: 'dict' object has no attribute 'find'
Is there any idea confirm that dict(headers) contain 'wp-admin' or transform the dict(headers) into text to use find function correctly?
In general, to find all items in a dict where the value contains a string:
[(key, value) for (key, value) in the_dict.items() if search_string in value]
(On python 2.x, use iteritems for efficiency.)
If you only need to know if it's there at all:
any(search_string in value for value in the_dict.values())
(On python 2.x you can use itervalues as well)
The error message is letting you know that the datatype dict doesn't have a find method available to it like other datatypes might. But the good news for you is that response.headers is already in a dictionary-like format so you can search for your "wp-admin" directly.
import urllib2
url = "http://www.google.com"
response = urllib2.urlopen(url)
for headername in response.headers:
print headername, response.headers[headername]
if "wp-admin" in response.headers:
print "header found"
It's just like this as well:
a = {"wp-admin":"value1",
"header2":"value2"}
if "wp-admin" in a:
print "Found header"
First of all, don't use str.find() to test for the presence of a substring; use in membership testing instead:
>>> 'foo' in 'there was once a foo that barred a bar'
True
>>> 'foo' in 'spam, ham and eggs'
False
To test for a substring in all values of a dictionary, loop over all values. To just test for the presence, use membership tests against each one. The any() function with a generator expression makes that a little more efficient by looping only enough to find a match:
if any('wp-admin' in v for v in response.headers.itervalues()):
Here dict.itervalues() yields all values in a dictionary lazily when looped over.
However, with request headers I'd normally expect the value to show up in just one header; you'd be better of looking for that specific header:
if 'wp-admin' in response.headers.get('set-cookie', ''):
where the .get() method will return '' if the Set-Cookie header is not present.
Related
I use python and this is my code
myUser = 'username'
myServer = 'http://api.url.net', "{\"orga\":\"monorga\",\"coupon\":\"moncoupon\"}"
myPass = 'pass'
authString = base64.encodestring('%s:%s' % (myUser, myPass))
headers = {'Authorization':"Basic %s" % authString}
req = urllib2.Request(myServer, None, headers)
openedUrl = urllib2.urlopen(req)
url = url.strip()
AttributeError: 'tuple' object has no attribute 'strip'
Please help me
When you write url = 'https://api.url.net', "{\"orga\":\"monorga\",\"coupon\":\"moncoupon\"}", basically you're just creating a tuple of two elements ('https://api.url.net' and "{\"orga\":\"monorga\",\"coupon\":\"moncoupon\"}"), and assigning a reference to this tuple to the url variable. This is due to the fact that, in python, there is not always the need to write the parenthesis of a tuple: a = 1, 2 for example.
Thus, url is now a tuple. Also, a tuple does not have a strip method, so you can't call url.strip.
To call strip on url, you must first convert it to a string.
I found this question whilst encountering this error message.
In my case, the problem was that I had an errant trailing comma on a line declaring a string, like so:
x = "my string",
x is therefore, I think quite strangely, a tuple of length one. First and only element is "my string".
This strikes me as an easy and confusing error to make, so I thought I'd put this answer here.
I have been trying to learn how to use sys.argv properly, while calling an executable file from the command line.
I wanted to have the functions results print to the command line when passing the filename and argument on the command line but, I get a TypeError.
So far I have:
#! /usr/bin/env python
import mechanize
from BeautifulSoup import BeautifulSoup
import sys
def dictionary(word):
br = mechanize.Browser()
response = br.open('http://www.dictionary.reference.com')
br.select_form(nr=0)
br.form['q'] = sys.argv
br.submit()
definition = BeautifulSoup(br.response().read())
trans = definition.findAll('td',{'class':'td3n2'})
fin = [i.text for i in trans]
query = {}
for i in fin:
query[fin.index(i)] = i
return query
print dictionary(sys.argv)
When I call this:
./this_file.py 'pass'
I am left with this error message:
Traceback (most recent call last):
File "./hot.py", line 20, in <module>
print dictionary(sys.argv)
File "./hot.py", line 10, in dictionary
br.form['q'] = sys.argv
File "/usr/local/lib/python2.7/dist-packages/mechanize/_form.py", line 2782, in __setitem__
control.value = value
File "/usr/local/lib/python2.7/dist-packages/mechanize/_form.py", line 1217, in __setattr__
raise TypeError("must assign a string")
TypeError: must assign a string
With
br.form['q'] = sys.argv
you are assigning a list of strings here instead of a string.
>>> type(sys.argv)
<type 'list'>
>>> type(sys.argv[0])
<type 'str'>
>>>
You want to identify a specific string to assign via an index.
Most likely it will be be index 1 given what you have in your post (and since index 0 is the name of the script). So perhaps
br.form['q'] = sys.argv[1]
will do for you. Of course it could be another index too, depending on your particular application/needs.
Note as #Dougal observes in a helpful comment below, the function parameter word in the function is not being used. You are calling your dictionary function sending it sys.argv and then ought to refer to word inside the function. The type doesn't change only the name that you refer to the command line args inside your function. The idea of word is good as it avoids the use of global variables. If you refer to use globals (not really encouraged) then removing word is recommended as it will be confusing to have it there).
So your statement should really read
br.form['q'] = word[1]
I'm learning Python and the project I've currently set myself includes sending a question from my laptop connected to the net, connect to the MIT START NLP database, enter the question, retrieve the response and display the response. I've read through the "HOWTO Fetch Internet Resources Using urllib2" at docs.python.org but I seem to be missing some poignant bit of this idea. Here's my code:
import urllib
import urllib2
question = raw_input("What is your question? ")
url = 'http://start.csail.mit.edu/'
values = question
data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
the_page = response.read()
print the_page
and here's the error I'm getting:
Traceback (most recent call last): File "mitstart.py", line 9, in
data = urllib.urlencode(values) File "/usr/lib/python2.7/urllib.py", line 1298, in urlencode
raise TypeError TypeError: not a valid non-string sequence or mapping object
So I'm thinking that the way I set question in vales was wrong, so I did
values = {question}
and values = (question)
and values = ('question')
with no joy.
(I know, and my response is "I'm learning, it's late, and suddenly my wife decided she needed to talk to me about something trivial while I was trying to figure this out)
Can I get some guidance or at least get pointed in the right direction?
Note that your error says: TypeError: not a valid non-string sequence or mapping object
So, while you've created values as a string, you need a non-string sequence or a mapping object.
urlencoding requires key value pairs (e.g. a mapping object or a dict), so you generally pass it a dictionary.
Looking at the source for the form, you'll see:
<input type="text" name="query" size="60">
This means you should create a dict, something like:
values = { 'query': 'What is your question?' }
Then you should be able to pass that as the argument to urlencode().
urllib.urlencode() doesn't accept a string as an argument.
As #ernie said you should specify query parameter. Also the url is missing the /startfarm.cgi part:
<form method="post" action="startfarm.cgi">
Updated example:
import cgi
from urllib import urlencode
from urllib2 import urlopen
data = urlencode(dict(query=raw_input("What is your question?"))).encode('ascii')
response = urlopen("http://start.csail.mit.edu/startfarm.cgi", data)
# extract encoding from Content-Type and print the response
_, params = cgi.parse_header(response.headers.get('Content-Type', ''))
print response.read().decode(params['charset'])
This question already has answers here:
How can I parse (read) and use JSON?
(5 answers)
Closed 29 days ago.
In Python I'm getting an error:
Exception: (<type 'exceptions.AttributeError'>,
AttributeError("'str' object has no attribute 'read'",), <traceback object at 0x1543ab8>)
Given python code:
def getEntries (self, sub):
url = 'http://www.reddit.com/'
if (sub != ''):
url += 'r/' + sub
request = urllib2.Request (url +
'.json', None, {'User-Agent' : 'Reddit desktop client by /user/RobinJ1995/'})
response = urllib2.urlopen (request)
jsonStr = response.read()
return json.load(jsonStr)['data']['children']
What does this error mean and what did I do to cause it?
The problem is that for json.load you should pass a file like object with a read function defined. So either you use json.load(response) or json.loads(response.read()).
Ok, this is an old thread but.
I had a same issue, my problem was I used json.load instead of json.loads
This way, json has no problem with loading any kind of dictionary.
Official documentation
json.load - Deserialize fp (a .read()-supporting text file or binary file containing a JSON document) to a Python object using this conversion table.
json.loads - Deserialize s (a str, bytes or bytearray instance containing a JSON document) to a Python object using this conversion table.
You need to open the file first. This doesn't work:
json_file = json.load('test.json')
But this works:
f = open('test.json')
json_file = json.load(f)
If you get a python error like this:
AttributeError: 'str' object has no attribute 'some_method'
You probably poisoned your object accidentally by overwriting your object with a string.
How to reproduce this error in python with a few lines of code:
#!/usr/bin/env python
import json
def foobar(json):
msg = json.loads(json)
foobar('{"batman": "yes"}')
Run it, which prints:
AttributeError: 'str' object has no attribute 'loads'
But change the name of the variablename, and it works fine:
#!/usr/bin/env python
import json
def foobar(jsonstring):
msg = json.loads(jsonstring)
foobar('{"batman": "yes"}')
This error is caused when you tried to run a method within a string. String has a few methods, but not the one you are invoking. So stop trying to invoke a method which String does not define and start looking for where you poisoned your object.
AttributeError("'str' object has no attribute 'read'",)
This means exactly what it says: something tried to find a .read attribute on the object that you gave it, and you gave it an object of type str (i.e., you gave it a string).
The error occurred here:
json.load(jsonStr)['data']['children']
Well, you aren't looking for read anywhere, so it must happen in the json.load function that you called (as indicated by the full traceback). That is because json.load is trying to .read the thing that you gave it, but you gave it jsonStr, which currently names a string (which you created by calling .read on the response).
Solution: don't call .read yourself; the function will do this, and is expecting you to give it the response directly so that it can do so.
You could also have figured this out by reading the built-in Python documentation for the function (try help(json.load), or for the entire module (try help(json)), or by checking the documentation for those functions on http://docs.python.org .
Instead of json.load() use json.loads() and it would work:
ex:
import json
from json import dumps
strinjJson = '{"event_type": "affected_element_added"}'
data = json.loads(strinjJson)
print(data)
So, don't use json.load(data.read()) use json.loads(data.read()):
def findMailOfDev(fileName):
file=open(fileName,'r')
data=file.read();
data=json.loads(data)
return data['mail']
use json.loads() function , put the s after that ... just a mistake btw i just realized after i searched error
def getEntries (self, sub):
url = 'http://www.reddit.com/'
if (sub != ''):
url += 'r/' + sub
request = urllib2.Request (url +
'.json', None, {'User-Agent' : 'Reddit desktop client by /user/RobinJ1995/'})
response = urllib2.urlopen (request)
jsonStr = response.read()
return json.loads(jsonStr)['data']['children']
try this
Open the file as a text file first
json_data = open("data.json", "r")
Now load it to dict
dict_data = json.load(json_data)
If you need to convert string to json. Then use loads() method instead of load(). load() function uses to load data from a file so used loads() to convert string to json object.
j_obj = json.loads('["label" : "data"]')
I'm trying to create a simple module for phenny, a simple IRC bot framework in Python. The module is supposed to go to http://www.isup.me/websitetheuserrequested to check is a website was up or down. I assumed I could use regex for the module seeing as other built-in modules use it too, so I tried creating this simple script although I don't think I did it right.
import re, urllib
import web
isupuri = 'http://www.isup.me/%s'
check = re.compile(r'(?ims)<span class="body">.*?</span>')
def isup(phenny, input):
global isupuri
global cleanup
bytes = web.get(isupuri)
quote = check.findall(bytes)
result = re.sub(r'<[^>]*?>', '', str(quote[0]))
phenny.say(result)
isup.commands = ['isup']
isup.priority = 'low'
isup.example = '.isup google.com'
It imports the required web packages (I think), and defines the string and the text to look for within the page. I really don't know what I did in those four lines, I kinda just ripped the code off another phenny module.
Here is an example of a quotes module that grabs a random quote from some webpage, I kinda tried to use that as a base: http://pastebin.com/vs5ypHZy
Does anyone know what I am doing wrong? If something needs clarified I can tell you, I don't think I explained this enough.
Here is the error I get:
Traceback (most recent call last):
File "C:\phenny\bot.py", line 189, in call
try: func(phenny, input)
File "C:\phenny\modules\isup.py", line 18, in isup
result = re.sub(r'<[^>]*?>', '', str(quote[0]))
IndexError: list index out of range
try this (from http://docs.python.org/release/2.6.7/library/httplib.html#examples):
import httplib
conn = httplib.HTTPConnection("www.python.org")
conn.request("HEAD","/index.html")
res = conn.getresponse()
if res.status >= 200 and res.status < 300:
print "up"
else:
print "down"
You will also need to add code to follow redirects before checking the response status.
edit
Alternative that does not need to handle redirects but uses exceptions for logic:
import urllib2
request = urllib2.Request('http://google.com')
request.get_method = lambda : 'HEAD'
try:
response = urllib2.urlopen(request)
print "up"
print response.code
except urllib2.URLError, e:
# failure
print "down"
print e
You should do your own tests and choose the best one.
The error means your regexp wasn't found anywhere on the page (the list quote has no element 0).