从HTML文件中存在的JavaScript代码中刮取数据

时间:2015-05-28 06:27:01

标签: javascript python web-scraping scrapy

我正在使用scrapy(Python)来清除http://www.heteropharmacy.com/outlets.html中的所有地址。城市/城镇下拉列表包含许多城市。每当我选择一个城市时,都会显示新地址。

但是,没有向服务器发出请求。我在Chrome中使用了firebug Lite和开发人员工具。没有向服务器发出POST / GET请求。

当我查看源代码时,我发现了这个:

<script src="jScript/myScript.js" type="text/javascript"></script>

当&#34; jScript / myScript.js&#34;点击后,我被重定向到http://www.heteropharmacy.com/jScript/myScript.js。此源代码是一个javascript文件,包含下拉框中所有城市的所有地址。这些地址在数组中。

我的问题是如何获取此javascript代码的html代码,以便我可以使用scrapy提取它。或者我可以直接从javascript文件中提取。我会感谢所有可能的解决方案,并且我愿意使用任何API而不仅仅是Scrapy。

我在互联网上搜索了很多,我只能找到那些向服务器发出请求的解决方案。

4 个答案:

答案 0 :(得分:0)

我会提取Javascript代码并使用一些库来执行JS代码并从那里检索结果,因为我可以看到代码将生成一个可以提取的JS数组。

也许这个用Python运行JS代码的库可以提供帮助 https://pypi.python.org/pypi/PyExecJS

答案 1 :(得分:0)

最好的方法是使用BeautifulSoup。首先,将原始myScript.js文件转换为HTML。您可以使用此HTML文件来创建汤。

创建汤后,使用正则表达式提取所需的数据。 假设您的HTML在html_doc

html_code = html_doc.encode('utf-8')
soup = BeautifulSoup(html_code)
script = soup.find_all("script")

'script'将包含一个javascript文件的字符串,可以使用正则表达式进行解析。希望这可以帮助。

答案 2 :(得分:0)

您还可以使用urllib2提取此数据,然后执行正则表达式。这可能有点乱,但有效。

import urllib2
import re

url = 'http://www.heteropharmacy.com/jScript/myScript.js'
data = urllib2.urlopen(url).read()
add_data = re.findall('new Array(.*?)\);', data, re.MULTILINE|re.DOTALL)

上面的代码会将javascript文件中的所有数组都提供给add_data列表。您可以再次使用re来获取地址。对于前者下面的行给你所有hyderabad地址。这可以根据您的要求进行优化

hyd_adds = re.findall('"(.*?)"', add_data[2])

答案 3 :(得分:0)

这里有多种选择:

  • 使用正则表达式直接从javascript中提取数据
  • 使用 javascript解析器直接从javascript中提取数据(例如Activity - example here
  • 使用ScrapyJS包与 Splash呈现javascript
  • 让{em>真正的浏览器在selenium的帮助下执行javascript - 浏览器可能无头(如PhantomJS)

如果你选择使用正则表达式,这里是你如何制作一个状态字典 - &gt;药房清单:

slimit

打印:

from pprint import pprint
import re

import requests


url = 'http://www.heteropharmacy.com/jScript/myScript.js'
with requests.Session() as session:
    response = session.get(url)

    pattern = re.compile(r"states_arr\['(\w+)'\]= new Array\((.*?)\);", re.MULTILINE | re.DOTALL)

    results = {state: [item.strip()[1:] for item in pharmacies.split('",')]
               for state, pharmacies in pattern.findall(response.content)}

    pprint(results)